cirq-core 1.7.0.dev20250825174419__py3-none-any.whl → 1.7.0.dev20251203004401__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.
- cirq/__init__.py +1 -0
- cirq/_compat.py +3 -2
- cirq/_compat_test.py +16 -15
- cirq/_doc.py +4 -3
- cirq/_import.py +2 -1
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/_bucket_priority_queue.py +2 -1
- cirq/circuits/circuit.py +19 -17
- cirq/circuits/circuit_operation.py +2 -1
- cirq/circuits/circuit_operation_test.py +19 -0
- cirq/circuits/circuit_test.py +31 -12
- cirq/circuits/frozen_circuit.py +3 -2
- cirq/circuits/moment.py +3 -15
- cirq/circuits/optimization_pass.py +2 -1
- cirq/circuits/qasm_output.py +39 -10
- cirq/circuits/qasm_output_test.py +51 -2
- cirq/circuits/text_diagram_drawer.py +2 -1
- cirq/contrib/acquaintance/bipartite.py +2 -1
- cirq/contrib/acquaintance/devices.py +1 -1
- cirq/contrib/acquaintance/executor.py +4 -5
- cirq/contrib/acquaintance/executor_test.py +2 -1
- cirq/contrib/acquaintance/gates.py +2 -1
- cirq/contrib/acquaintance/gates_test.py +1 -1
- cirq/contrib/acquaintance/inspection_utils.py +2 -1
- cirq/contrib/acquaintance/mutation_utils.py +2 -1
- cirq/contrib/acquaintance/optimizers.py +2 -1
- cirq/contrib/acquaintance/permutation.py +2 -1
- cirq/contrib/acquaintance/permutation_test.py +1 -1
- cirq/contrib/acquaintance/shift.py +2 -1
- cirq/contrib/acquaintance/shift_swap_network.py +2 -1
- cirq/contrib/acquaintance/strategies/complete.py +3 -2
- cirq/contrib/acquaintance/strategies/cubic.py +2 -1
- cirq/contrib/acquaintance/strategies/quartic_paired.py +2 -1
- cirq/contrib/acquaintance/strategies/quartic_paired_test.py +1 -1
- cirq/contrib/acquaintance/testing.py +2 -1
- cirq/contrib/acquaintance/topological_sort.py +2 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +3 -2
- cirq/contrib/circuitdag/circuit_dag.py +4 -2
- cirq/contrib/custom_simulators/custom_state_simulator.py +2 -1
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +1 -1
- cirq/contrib/graph_device/graph_device.py +2 -1
- cirq/contrib/graph_device/graph_device_test.py +2 -1
- cirq/contrib/graph_device/hypergraph.py +2 -1
- cirq/contrib/graph_device/uniform_graph_device.py +2 -1
- cirq/contrib/json.py +14 -2
- cirq/contrib/json_test_data/BayesianNetworkGate.json +10 -0
- cirq/contrib/json_test_data/BayesianNetworkGate.repr +3 -0
- cirq/contrib/json_test_data/QuantumVolumeResult.json +169 -0
- cirq/contrib/json_test_data/QuantumVolumeResult.repr +22 -0
- cirq/contrib/json_test_data/SwapPermutationGate.json +3 -0
- cirq/contrib/json_test_data/SwapPermutationGate.repr +1 -0
- cirq/contrib/json_test_data/spec.py +0 -2
- cirq/contrib/noise_models/noise_models.py +2 -1
- cirq/contrib/paulistring/clifford_optimize.py +20 -2
- cirq/contrib/paulistring/optimize.py +1 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +146 -35
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +81 -178
- cirq/contrib/paulistring/recombine.py +5 -2
- cirq/contrib/paulistring/separate.py +1 -1
- cirq/contrib/qasm_import/_lexer.py +6 -1
- cirq/contrib/qasm_import/_lexer_test.py +1 -1
- cirq/contrib/qasm_import/_parser.py +24 -8
- cirq/contrib/qasm_import/_parser_test.py +44 -6
- cirq/contrib/qcircuit/qcircuit_pdf_test.py +6 -9
- cirq/contrib/quantikz/__init__.py +21 -0
- cirq/contrib/quantikz/circuit_to_latex_quantikz.py +680 -0
- cirq/contrib/quantikz/circuit_to_latex_quantikz_test.py +253 -0
- cirq/contrib/quantikz/circuit_to_latex_render.py +424 -0
- cirq/contrib/quantikz/circuit_to_latex_render_test.py +44 -0
- cirq/contrib/quantum_volume/quantum_volume.py +2 -1
- cirq/contrib/quimb/density_matrix.py +1 -1
- cirq/contrib/quimb/grid_circuits.py +2 -1
- cirq/contrib/quimb/grid_circuits_test.py +1 -1
- cirq/contrib/quimb/mps_simulator.py +4 -3
- cirq/contrib/quimb/state_vector.py +2 -1
- cirq/contrib/quirk/export_to_quirk.py +2 -1
- cirq/contrib/quirk/linearize_circuit.py +1 -1
- cirq/contrib/quirk/quirk_gate.py +2 -1
- cirq/contrib/routing/device.py +1 -1
- cirq/contrib/routing/greedy.py +2 -1
- cirq/contrib/routing/initialization.py +2 -1
- cirq/contrib/routing/router.py +2 -1
- cirq/contrib/routing/swap_network.py +2 -1
- cirq/contrib/routing/utils.py +2 -1
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +7 -5
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +6 -6
- cirq/devices/device.py +2 -1
- cirq/devices/grid_device_metadata.py +2 -1
- cirq/devices/grid_qubit.py +7 -6
- cirq/devices/insertion_noise_model.py +2 -1
- cirq/devices/line_qubit.py +2 -1
- cirq/devices/named_topologies.py +2 -1
- cirq/devices/noise_model.py +2 -1
- cirq/devices/noise_model_test.py +1 -1
- cirq/devices/noise_properties.py +2 -1
- cirq/devices/superconducting_qubits_noise_properties_test.py +2 -1
- cirq/devices/thermal_noise_model.py +2 -1
- cirq/experiments/__init__.py +2 -0
- cirq/experiments/benchmarking/parallel_xeb.py +2 -1
- cirq/experiments/benchmarking/parallel_xeb_test.py +1 -1
- cirq/experiments/fidelity_estimation.py +2 -1
- cirq/experiments/fidelity_estimation_test.py +1 -1
- cirq/experiments/ghz_2d.py +150 -0
- cirq/experiments/ghz_2d_test.py +155 -0
- cirq/experiments/n_qubit_tomography.py +2 -1
- cirq/experiments/n_qubit_tomography_test.py +1 -1
- cirq/experiments/purity_estimation.py +1 -1
- cirq/experiments/qubit_characterizations.py +33 -4
- cirq/experiments/qubit_characterizations_test.py +16 -0
- cirq/experiments/random_quantum_circuit_generation.py +2 -1
- cirq/experiments/random_quantum_circuit_generation_test.py +2 -1
- cirq/experiments/readout_confusion_matrix.py +2 -1
- cirq/experiments/readout_confusion_matrix_test.py +1 -1
- cirq/experiments/single_qubit_readout_calibration.py +2 -1
- cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
- cirq/experiments/t1_decay_experiment.py +2 -1
- cirq/experiments/two_qubit_xeb.py +2 -1
- cirq/experiments/two_qubit_xeb_test.py +1 -1
- cirq/experiments/xeb_fitting.py +2 -1
- cirq/experiments/xeb_fitting_test.py +1 -1
- cirq/experiments/xeb_sampling.py +5 -3
- cirq/experiments/xeb_sampling_test.py +1 -1
- cirq/experiments/xeb_simulation.py +2 -1
- cirq/experiments/xeb_simulation_test.py +2 -1
- cirq/experiments/z_phase_calibration.py +2 -1
- cirq/experiments/z_phase_calibration_test.py +18 -3
- cirq/interop/quirk/cells/__init__.py +1 -2
- cirq/interop/quirk/cells/all_cells.py +2 -1
- cirq/interop/quirk/cells/arithmetic_cells.py +2 -1
- cirq/interop/quirk/cells/cell.py +2 -1
- cirq/interop/quirk/cells/composite_cell.py +2 -1
- cirq/interop/quirk/cells/composite_cell_test.py +1 -1
- cirq/interop/quirk/cells/control_cells.py +2 -1
- cirq/interop/quirk/cells/frequency_space_cells.py +1 -1
- cirq/interop/quirk/cells/ignored_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells.py +2 -1
- cirq/interop/quirk/cells/input_rotation_cells.py +2 -1
- cirq/interop/quirk/cells/measurement_cells.py +2 -1
- cirq/interop/quirk/cells/parse.py +2 -11
- cirq/interop/quirk/cells/qubit_permutation_cells.py +2 -1
- cirq/interop/quirk/cells/scalar_cells.py +2 -1
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +2 -1
- cirq/interop/quirk/cells/swap_cell.py +2 -1
- cirq/interop/quirk/cells/unsupported_cells.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +2 -1
- cirq/json_resolver_cache.py +0 -2
- cirq/linalg/decompositions.py +6 -2
- cirq/linalg/decompositions_test.py +1 -0
- cirq/linalg/diagonalize.py +1 -1
- cirq/linalg/predicates.py +2 -1
- cirq/linalg/tolerance.py +2 -1
- cirq/linalg/transformations.py +3 -2
- cirq/ops/arithmetic_operation.py +4 -3
- cirq/ops/arithmetic_operation_test.py +1 -1
- cirq/ops/boolean_hamiltonian.py +4 -3
- cirq/ops/classically_controlled_operation.py +11 -11
- cirq/ops/classically_controlled_operation_test.py +26 -2
- cirq/ops/clifford_gate.py +3 -2
- cirq/ops/clifford_gate_test.py +1 -2
- cirq/ops/common_channels.py +2 -1
- cirq/ops/common_gates.py +3 -2
- cirq/ops/control_values.py +2 -1
- cirq/ops/controlled_gate.py +3 -2
- cirq/ops/controlled_gate_test.py +2 -1
- cirq/ops/controlled_operation.py +3 -2
- cirq/ops/controlled_operation_test.py +2 -1
- cirq/ops/dense_pauli_string.py +44 -81
- cirq/ops/dense_pauli_string_test.py +21 -0
- cirq/ops/diagonal_gate.py +3 -2
- cirq/ops/eigen_gate.py +9 -7
- cirq/ops/fourier_transform.py +3 -2
- cirq/ops/fourier_transform_test.py +2 -4
- cirq/ops/fsim_gate.py +3 -2
- cirq/ops/gate_operation.py +23 -12
- cirq/ops/gateset.py +22 -2
- cirq/ops/global_phase_op.py +3 -2
- cirq/ops/greedy_qubit_manager.py +2 -1
- cirq/ops/identity.py +2 -1
- cirq/ops/kraus_channel.py +2 -1
- cirq/ops/linear_combinations.py +12 -17
- cirq/ops/linear_combinations_test.py +23 -1
- cirq/ops/matrix_gates.py +2 -1
- cirq/ops/measure_util.py +8 -6
- cirq/ops/measurement_gate.py +2 -1
- cirq/ops/mixed_unitary_channel.py +2 -1
- cirq/ops/named_qubit.py +2 -2
- cirq/ops/op_tree.py +2 -1
- cirq/ops/parallel_gate.py +3 -2
- cirq/ops/parity_gates.py +2 -1
- cirq/ops/parity_gates_test.py +35 -0
- cirq/ops/pauli_interaction_gate.py +2 -1
- cirq/ops/pauli_measurement_gate.py +2 -1
- cirq/ops/pauli_string.py +37 -57
- cirq/ops/pauli_string_phasor.py +6 -5
- cirq/ops/pauli_string_raw_types.py +2 -1
- cirq/ops/pauli_string_test.py +49 -6
- cirq/ops/pauli_sum_exponential.py +2 -1
- cirq/ops/permutation_gate.py +2 -1
- cirq/ops/phased_iswap_gate.py +3 -2
- cirq/ops/phased_x_gate.py +5 -4
- cirq/ops/phased_x_z_gate.py +12 -5
- cirq/ops/projector.py +2 -1
- cirq/ops/qubit_manager.py +2 -1
- cirq/ops/qubit_order.py +2 -1
- cirq/ops/qubit_order_or_list.py +1 -1
- cirq/ops/random_gate_channel.py +3 -2
- cirq/ops/raw_types.py +33 -16
- cirq/ops/raw_types_test.py +4 -3
- cirq/ops/state_preparation_channel.py +2 -1
- cirq/ops/three_qubit_gates.py +3 -2
- cirq/ops/two_qubit_diagonal_gate.py +3 -2
- cirq/ops/uniform_superposition_gate.py +2 -1
- cirq/ops/wait_gate.py +10 -4
- cirq/protocols/act_on_protocol.py +2 -1
- cirq/protocols/act_on_protocol_test.py +2 -1
- cirq/protocols/apply_channel_protocol.py +2 -1
- cirq/protocols/apply_mixture_protocol.py +2 -1
- cirq/protocols/apply_mixture_protocol_test.py +2 -1
- cirq/protocols/apply_unitary_protocol.py +2 -1
- cirq/protocols/apply_unitary_protocol_test.py +2 -0
- cirq/protocols/approximate_equality_protocol.py +2 -1
- cirq/protocols/circuit_diagram_info_protocol.py +2 -1
- cirq/protocols/control_key_protocol.py +7 -0
- cirq/protocols/decompose_protocol.py +2 -12
- cirq/protocols/has_stabilizer_effect_protocol.py +1 -1
- cirq/protocols/has_stabilizer_effect_protocol_test.py +11 -9
- cirq/protocols/has_unitary_protocol_test.py +3 -3
- cirq/protocols/hash_from_pickle_test.py +2 -2
- cirq/protocols/inverse_protocol.py +2 -1
- cirq/protocols/json_serialization.py +5 -4
- cirq/protocols/json_serialization_test.py +31 -31
- cirq/protocols/kraus_protocol.py +4 -3
- cirq/protocols/kraus_protocol_test.py +7 -7
- cirq/protocols/measurement_key_protocol.py +32 -8
- cirq/protocols/mixture_protocol.py +3 -2
- cirq/protocols/mixture_protocol_test.py +7 -7
- cirq/protocols/mul_protocol_test.py +4 -4
- cirq/protocols/phase_protocol.py +13 -4
- cirq/protocols/pow_protocol.py +2 -1
- cirq/protocols/pow_protocol_test.py +5 -5
- cirq/protocols/qasm.py +2 -1
- cirq/protocols/qid_shape_protocol.py +2 -1
- cirq/protocols/resolve_parameters.py +17 -15
- cirq/protocols/trace_distance_bound.py +2 -1
- cirq/protocols/unitary_protocol.py +21 -21
- cirq/protocols/unitary_protocol_test.py +31 -19
- cirq/qis/channels.py +1 -1
- cirq/qis/channels_test.py +1 -1
- cirq/qis/clifford_tableau.py +16 -15
- cirq/qis/clifford_tableau_test.py +17 -17
- cirq/qis/entropy.py +3 -3
- cirq/qis/entropy_test.py +1 -1
- cirq/qis/quantum_state_representation.py +2 -1
- cirq/qis/states.py +7 -2
- cirq/qis/states_test.py +54 -54
- cirq/sim/classical_simulator.py +25 -14
- cirq/sim/classical_simulator_test.py +85 -30
- cirq/sim/clifford/clifford_simulator.py +7 -6
- cirq/sim/clifford/clifford_simulator_test.py +51 -50
- cirq/sim/clifford/clifford_tableau_simulation_state.py +2 -1
- cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +2 -1
- cirq/sim/clifford/stabilizer_sampler.py +1 -1
- cirq/sim/clifford/stabilizer_simulation_state.py +2 -1
- cirq/sim/clifford/stabilizer_state_ch_form.py +16 -15
- cirq/sim/clifford/stabilizer_state_ch_form_test.py +0 -1
- cirq/sim/density_matrix_simulation_state.py +7 -6
- cirq/sim/density_matrix_simulator.py +3 -2
- cirq/sim/density_matrix_simulator_test.py +94 -84
- cirq/sim/density_matrix_utils.py +2 -1
- cirq/sim/density_matrix_utils_test.py +1 -1
- cirq/sim/mux.py +35 -8
- cirq/sim/mux_test.py +39 -26
- cirq/sim/simulation_product_state.py +2 -1
- cirq/sim/simulation_product_state_test.py +8 -7
- cirq/sim/simulation_state.py +6 -5
- cirq/sim/simulation_state_base.py +3 -2
- cirq/sim/simulation_state_test.py +7 -6
- cirq/sim/simulation_utils.py +2 -1
- cirq/sim/simulator.py +4 -3
- cirq/sim/simulator_base.py +2 -1
- cirq/sim/simulator_base_test.py +51 -36
- cirq/sim/simulator_test.py +41 -36
- cirq/sim/sparse_simulator.py +3 -2
- cirq/sim/sparse_simulator_test.py +92 -82
- cirq/sim/state_vector.py +5 -6
- cirq/sim/state_vector_simulation_state.py +10 -9
- cirq/sim/state_vector_simulator.py +2 -1
- cirq/sim/state_vector_simulator_test.py +9 -9
- cirq/sim/state_vector_test.py +40 -39
- cirq/study/__init__.py +1 -0
- cirq/study/flatten_expressions.py +2 -1
- cirq/study/resolver.py +31 -18
- cirq/study/resolver_test.py +1 -1
- cirq/study/result.py +2 -1
- cirq/study/result_test.py +20 -20
- cirq/study/sweepable.py +2 -1
- cirq/study/sweepable_test.py +20 -20
- cirq/study/sweeps.py +26 -1
- cirq/study/sweeps_test.py +67 -43
- cirq/testing/_compat_test_data/__init__.py +3 -3
- cirq/testing/circuit_compare.py +2 -1
- cirq/testing/circuit_compare_test.py +16 -14
- cirq/testing/consistent_act_on_test.py +1 -1
- cirq/testing/consistent_channels.py +2 -2
- cirq/testing/consistent_controlled_gate_op.py +2 -2
- cirq/testing/consistent_controlled_gate_op_test.py +2 -1
- cirq/testing/consistent_decomposition.py +4 -2
- cirq/testing/consistent_phase_by.py +1 -1
- cirq/testing/consistent_protocols.py +2 -1
- cirq/testing/consistent_protocols_test.py +3 -3
- cirq/testing/consistent_qasm.py +4 -3
- cirq/testing/consistent_qasm_test.py +3 -3
- cirq/testing/consistent_resolve_parameters.py +1 -1
- cirq/testing/consistent_unitary.py +1 -1
- cirq/testing/consistent_unitary_test.py +1 -1
- cirq/testing/deprecation.py +1 -1
- cirq/testing/devices.py +3 -2
- cirq/testing/equals_tester.py +4 -3
- cirq/testing/equivalent_basis_map.py +4 -2
- cirq/testing/json.py +3 -2
- cirq/testing/lin_alg_utils.py +1 -1
- cirq/testing/logs.py +1 -1
- cirq/testing/op_tree.py +1 -1
- cirq/testing/order_tester.py +2 -2
- cirq/testing/pytest_utils.py +2 -1
- cirq/testing/random_circuit.py +2 -1
- cirq/testing/random_circuit_test.py +2 -1
- cirq/testing/repr_pretty_tester.py +3 -3
- cirq/transformers/__init__.py +1 -0
- cirq/transformers/_connected_component.py +231 -0
- cirq/transformers/_connected_component_test.py +200 -0
- cirq/transformers/align_test.py +13 -13
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +8 -7
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +5 -5
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +11 -10
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +6 -6
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +3 -2
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +11 -10
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +8 -7
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +17 -20
- cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +33 -27
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -1
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +12 -11
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +3 -3
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +32 -30
- cirq/transformers/drop_negligible_operations_test.py +7 -7
- cirq/transformers/dynamical_decoupling.py +185 -112
- cirq/transformers/dynamical_decoupling_test.py +195 -201
- cirq/transformers/eject_phased_paulis.py +2 -1
- cirq/transformers/eject_phased_paulis_test.py +3 -2
- cirq/transformers/eject_z.py +5 -3
- cirq/transformers/eject_z_test.py +23 -25
- cirq/transformers/expand_composite.py +3 -2
- cirq/transformers/expand_composite_test.py +14 -14
- cirq/transformers/gauge_compiling/__init__.py +13 -0
- cirq/transformers/gauge_compiling/gauge_compiling.py +3 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +14 -12
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +3 -3
- cirq/transformers/gauge_compiling/idle_moments_gauge.py +225 -0
- cirq/transformers/gauge_compiling/idle_moments_gauge_test.py +193 -0
- cirq/transformers/gauge_compiling/multi_moment_cphase_gauge.py +242 -0
- cirq/transformers/gauge_compiling/multi_moment_cphase_gauge_test.py +243 -0
- cirq/transformers/gauge_compiling/multi_moment_gauge_compiling.py +151 -0
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +1 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +6 -6
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +3 -2
- cirq/transformers/measurement_transformers.py +2 -1
- cirq/transformers/measurement_transformers_test.py +45 -39
- cirq/transformers/merge_k_qubit_gates.py +2 -1
- cirq/transformers/merge_k_qubit_gates_test.py +1 -1
- cirq/transformers/merge_single_qubit_gates.py +9 -5
- cirq/transformers/merge_single_qubit_gates_test.py +22 -22
- cirq/transformers/noise_adding_test.py +2 -2
- cirq/transformers/optimize_for_target_gateset.py +2 -1
- cirq/transformers/optimize_for_target_gateset_test.py +11 -9
- cirq/transformers/qubit_management_transformers_test.py +6 -2
- cirq/transformers/routing/mapping_manager.py +2 -1
- cirq/transformers/routing/route_circuit_cqc.py +2 -1
- cirq/transformers/stratify.py +2 -1
- cirq/transformers/symbolize.py +2 -1
- cirq/transformers/tag_transformers.py +2 -1
- cirq/transformers/target_gatesets/compilation_target_gateset.py +2 -1
- cirq/transformers/target_gatesets/cz_gateset.py +2 -1
- cirq/transformers/target_gatesets/cz_gateset_test.py +1 -1
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +2 -1
- cirq/transformers/transformer_api.py +2 -1
- cirq/transformers/transformer_primitives.py +271 -145
- cirq/transformers/transformer_primitives_test.py +185 -1
- cirq/value/abc_alt.py +2 -1
- cirq/value/classical_data.py +2 -1
- cirq/value/condition.py +2 -1
- cirq/value/digits.py +9 -2
- cirq/value/duration.py +6 -5
- cirq/value/linear_dict.py +4 -9
- cirq/value/measurement_key.py +2 -1
- cirq/value/periodic_value.py +3 -2
- cirq/value/product_state.py +2 -1
- cirq/value/value_equality_attr.py +2 -1
- cirq/vis/density_matrix.py +1 -1
- cirq/vis/heatmap.py +2 -1
- cirq/vis/histogram.py +2 -1
- cirq/vis/state_histogram.py +2 -1
- cirq/work/collector.py +2 -1
- cirq/work/observable_grouping.py +2 -1
- cirq/work/observable_measurement.py +2 -1
- cirq/work/observable_measurement_data.py +2 -1
- cirq/work/observable_measurement_test.py +1 -1
- cirq/work/observable_readout_calibration.py +2 -1
- cirq/work/observable_readout_calibration_test.py +1 -1
- cirq/work/observable_settings.py +2 -1
- cirq/work/sampler.py +2 -1
- cirq/work/sampler_test.py +1 -1
- {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/METADATA +5 -6
- {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/RECORD +425 -406
- cirq/contrib/json_test.py +0 -33
- {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/WHEEL +0 -0
- {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.7.0.dev20250825174419.dist-info → cirq_core-1.7.0.dev20251203004401.dist-info}/top_level.txt +0 -0
cirq/ops/controlled_operation.py
CHANGED
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
from collections.abc import Collection, Sequence, Set
|
|
17
18
|
from types import EllipsisType, NotImplementedType
|
|
18
|
-
from typing import
|
|
19
|
+
from typing import Any, TYPE_CHECKING
|
|
19
20
|
|
|
20
21
|
import numpy as np
|
|
21
22
|
|
|
@@ -261,7 +262,7 @@ class ControlledOperation(raw_types.Operation):
|
|
|
261
262
|
def _is_parameterized_(self) -> bool:
|
|
262
263
|
return protocols.is_parameterized(self.sub_operation)
|
|
263
264
|
|
|
264
|
-
def _parameter_names_(self) ->
|
|
265
|
+
def _parameter_names_(self) -> Set[str]:
|
|
265
266
|
return protocols.parameter_names(self.sub_operation)
|
|
266
267
|
|
|
267
268
|
def _resolve_parameters_(
|
|
@@ -16,8 +16,9 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import itertools
|
|
18
18
|
import re
|
|
19
|
+
from collections.abc import Sequence
|
|
19
20
|
from types import EllipsisType, NotImplementedType
|
|
20
|
-
from typing import cast
|
|
21
|
+
from typing import cast
|
|
21
22
|
|
|
22
23
|
import numpy as np
|
|
23
24
|
import pytest
|
cirq/ops/dense_pauli_string.py
CHANGED
|
@@ -16,19 +16,9 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import abc
|
|
18
18
|
import numbers
|
|
19
|
+
from collections.abc import Callable, Iterable, Iterator, Sequence, Set
|
|
19
20
|
from types import NotImplementedType
|
|
20
|
-
from typing import
|
|
21
|
-
AbstractSet,
|
|
22
|
-
Any,
|
|
23
|
-
Callable,
|
|
24
|
-
cast,
|
|
25
|
-
Iterable,
|
|
26
|
-
Iterator,
|
|
27
|
-
overload,
|
|
28
|
-
Self,
|
|
29
|
-
Sequence,
|
|
30
|
-
TYPE_CHECKING,
|
|
31
|
-
)
|
|
21
|
+
from typing import Any, cast, overload, Self, TYPE_CHECKING
|
|
32
22
|
|
|
33
23
|
import numpy as np
|
|
34
24
|
import sympy
|
|
@@ -187,7 +177,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
187
177
|
def _is_parameterized_(self) -> bool:
|
|
188
178
|
return protocols.is_parameterized(self.coefficient)
|
|
189
179
|
|
|
190
|
-
def _parameter_names_(self) ->
|
|
180
|
+
def _parameter_names_(self) -> Set[str]:
|
|
191
181
|
return protocols.parameter_names(self.coefficient)
|
|
192
182
|
|
|
193
183
|
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> Self:
|
|
@@ -247,35 +237,25 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
247
237
|
|
|
248
238
|
def __mul__(self, other):
|
|
249
239
|
concrete_class = type(self)
|
|
250
|
-
if isinstance(other, BaseDensePauliString):
|
|
251
|
-
if isinstance(other, MutableDensePauliString):
|
|
252
|
-
concrete_class = MutableDensePauliString
|
|
253
|
-
max_len = max(len(self.pauli_mask), len(other.pauli_mask))
|
|
254
|
-
min_len = min(len(self.pauli_mask), len(other.pauli_mask))
|
|
255
|
-
new_mask = np.zeros(max_len, dtype=np.uint8)
|
|
256
|
-
new_mask[: len(self.pauli_mask)] ^= self.pauli_mask
|
|
257
|
-
new_mask[: len(other.pauli_mask)] ^= other.pauli_mask
|
|
258
|
-
tweak = _vectorized_pauli_mul_phase(
|
|
259
|
-
self.pauli_mask[:min_len], other.pauli_mask[:min_len]
|
|
260
|
-
)
|
|
261
|
-
return concrete_class(
|
|
262
|
-
pauli_mask=new_mask, coefficient=self.coefficient * other.coefficient * tweak
|
|
263
|
-
)
|
|
264
|
-
|
|
265
240
|
if isinstance(other, (sympy.Basic, numbers.Number)):
|
|
266
241
|
new_coef = protocols.mul(self.coefficient, other, default=None)
|
|
267
242
|
if new_coef is None:
|
|
268
243
|
return NotImplemented
|
|
269
244
|
return concrete_class(pauli_mask=self.pauli_mask, coefficient=new_coef)
|
|
270
245
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
246
|
+
if (other_dps := _try_interpret_as_dps(other)) is not None:
|
|
247
|
+
if isinstance(other_dps, MutableDensePauliString):
|
|
248
|
+
concrete_class = MutableDensePauliString
|
|
249
|
+
max_len = max(len(self.pauli_mask), len(other_dps.pauli_mask))
|
|
250
|
+
min_len = min(len(self.pauli_mask), len(other_dps.pauli_mask))
|
|
251
|
+
new_mask = np.zeros(max_len, dtype=np.uint8)
|
|
252
|
+
new_mask[: len(self.pauli_mask)] ^= self.pauli_mask
|
|
253
|
+
new_mask[: len(other_dps.pauli_mask)] ^= other_dps.pauli_mask
|
|
254
|
+
tweak = _vectorized_pauli_mul_phase(
|
|
255
|
+
self.pauli_mask[:min_len], other_dps.pauli_mask[:min_len]
|
|
256
|
+
)
|
|
276
257
|
return concrete_class(
|
|
277
|
-
pauli_mask=
|
|
278
|
-
coefficient=self.coefficient * _vectorized_pauli_mul_phase(self.pauli_mask[i], p),
|
|
258
|
+
pauli_mask=new_mask, coefficient=self.coefficient * other_dps.coefficient * tweak
|
|
279
259
|
)
|
|
280
260
|
|
|
281
261
|
return NotImplemented
|
|
@@ -284,15 +264,8 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
284
264
|
if isinstance(other, (sympy.Basic, numbers.Number)):
|
|
285
265
|
return self.__mul__(other)
|
|
286
266
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
p, i = split
|
|
290
|
-
mask = np.copy(self.pauli_mask)
|
|
291
|
-
mask[i] ^= p
|
|
292
|
-
return type(self)(
|
|
293
|
-
pauli_mask=mask,
|
|
294
|
-
coefficient=self.coefficient * _vectorized_pauli_mul_phase(p, self.pauli_mask[i]),
|
|
295
|
-
)
|
|
267
|
+
if other := _try_interpret_as_dps(other):
|
|
268
|
+
return other.__mul__(self)
|
|
296
269
|
|
|
297
270
|
return NotImplemented
|
|
298
271
|
|
|
@@ -369,18 +342,11 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
369
342
|
)
|
|
370
343
|
|
|
371
344
|
def _commutes_(self, other: Any, *, atol: float = 1e-8) -> bool | NotImplementedType | None:
|
|
372
|
-
if
|
|
373
|
-
n = min(len(self.pauli_mask), len(
|
|
374
|
-
phase = _vectorized_pauli_mul_phase(self.pauli_mask[:n],
|
|
345
|
+
if (other_dps := _try_interpret_as_dps(other)) is not None:
|
|
346
|
+
n = min(len(self.pauli_mask), len(other_dps.pauli_mask))
|
|
347
|
+
phase = _vectorized_pauli_mul_phase(self.pauli_mask[:n], other_dps.pauli_mask[:n])
|
|
375
348
|
return phase == 1 or phase == -1
|
|
376
349
|
|
|
377
|
-
# Single qubit Pauli operation.
|
|
378
|
-
split = _attempt_value_to_pauli_index(other)
|
|
379
|
-
if split is not None:
|
|
380
|
-
p1, i = split
|
|
381
|
-
p2 = self.pauli_mask[i]
|
|
382
|
-
return (p1 or p2) == (p2 or p1)
|
|
383
|
-
|
|
384
350
|
return NotImplemented
|
|
385
351
|
|
|
386
352
|
def frozen(self) -> DensePauliString:
|
|
@@ -518,20 +484,6 @@ class MutableDensePauliString(BaseDensePauliString):
|
|
|
518
484
|
return NotImplemented
|
|
519
485
|
|
|
520
486
|
def __imul__(self, other):
|
|
521
|
-
if isinstance(other, BaseDensePauliString):
|
|
522
|
-
if len(other) > len(self):
|
|
523
|
-
raise ValueError(
|
|
524
|
-
"The receiving dense pauli string is smaller than "
|
|
525
|
-
"the dense pauli string being multiplied into it.\n"
|
|
526
|
-
f"self={repr(self)}\n"
|
|
527
|
-
f"other={repr(other)}"
|
|
528
|
-
)
|
|
529
|
-
self_mask = self.pauli_mask[: len(other.pauli_mask)]
|
|
530
|
-
self._coefficient *= _vectorized_pauli_mul_phase(self_mask, other.pauli_mask)
|
|
531
|
-
self._coefficient *= other.coefficient
|
|
532
|
-
self_mask ^= other.pauli_mask
|
|
533
|
-
return self
|
|
534
|
-
|
|
535
487
|
if isinstance(other, (sympy.Basic, numbers.Number)):
|
|
536
488
|
new_coef = protocols.mul(self.coefficient, other, default=None)
|
|
537
489
|
if new_coef is None:
|
|
@@ -539,11 +491,18 @@ class MutableDensePauliString(BaseDensePauliString):
|
|
|
539
491
|
self._coefficient = new_coef if isinstance(new_coef, sympy.Basic) else complex(new_coef)
|
|
540
492
|
return self
|
|
541
493
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
494
|
+
if (other_dps := _try_interpret_as_dps(other)) is not None:
|
|
495
|
+
if len(other_dps) > len(self):
|
|
496
|
+
raise ValueError(
|
|
497
|
+
"The receiving dense pauli string is smaller than "
|
|
498
|
+
"the dense pauli string being multiplied into it.\n"
|
|
499
|
+
f"self={repr(self)}\n"
|
|
500
|
+
f"other={repr(other)}"
|
|
501
|
+
)
|
|
502
|
+
self_mask = self.pauli_mask[: len(other_dps.pauli_mask)]
|
|
503
|
+
self._coefficient *= _vectorized_pauli_mul_phase(self_mask, other_dps.pauli_mask)
|
|
504
|
+
self._coefficient *= other_dps.coefficient
|
|
505
|
+
self_mask ^= other_dps.pauli_mask
|
|
547
506
|
return self
|
|
548
507
|
|
|
549
508
|
return NotImplemented
|
|
@@ -613,23 +572,27 @@ def _as_pauli_mask(val: Iterable[cirq.PAULI_GATE_LIKE] | np.ndarray) -> np.ndarr
|
|
|
613
572
|
return np.array([_pauli_index(v) for v in val], dtype=np.uint8)
|
|
614
573
|
|
|
615
574
|
|
|
616
|
-
def
|
|
617
|
-
if
|
|
618
|
-
return
|
|
575
|
+
def _try_interpret_as_dps(v: cirq.Operation) -> BaseDensePauliString | None:
|
|
576
|
+
if isinstance(v, BaseDensePauliString):
|
|
577
|
+
return v
|
|
619
578
|
|
|
620
|
-
if
|
|
621
|
-
return None
|
|
579
|
+
if (ps := pauli_string._try_interpret_as_pauli_string(v)) is None:
|
|
580
|
+
return None
|
|
622
581
|
|
|
623
|
-
q = v.qubits[0]
|
|
624
582
|
from cirq import devices
|
|
625
583
|
|
|
626
|
-
if not isinstance(q, devices.LineQubit):
|
|
584
|
+
if not all(isinstance(q, devices.LineQubit) for q in ps.qubits):
|
|
627
585
|
raise ValueError(
|
|
628
586
|
'Got a Pauli operation, but it was applied to a qubit type '
|
|
629
587
|
'other than `cirq.LineQubit` so its dense index is ambiguous.\n'
|
|
630
588
|
f'v={repr(v)}.'
|
|
631
589
|
)
|
|
632
|
-
|
|
590
|
+
|
|
591
|
+
pauli_mask = np.zeros(max((q.x + 1 for q in ps.qubits), default=0), dtype=np.uint8)
|
|
592
|
+
for q in ps.qubits:
|
|
593
|
+
pauli_mask[q.x] = pauli_string.PAULI_GATE_LIKE_TO_INDEX_MAP[ps[q]]
|
|
594
|
+
|
|
595
|
+
return DensePauliString(pauli_mask)
|
|
633
596
|
|
|
634
597
|
|
|
635
598
|
def _vectorized_pauli_mul_phase(lhs: int | np.ndarray, rhs: int | np.ndarray) -> complex:
|
|
@@ -173,6 +173,10 @@ def test_mul() -> None:
|
|
|
173
173
|
with pytest.raises(ValueError, match='other than `cirq.LineQubit'):
|
|
174
174
|
_ = f('III') * cirq.X(cirq.NamedQubit('tmp'))
|
|
175
175
|
|
|
176
|
+
# Parity operations.
|
|
177
|
+
assert f('IXYZ') * cirq.XX(*cirq.LineQubit.range(1, 3)) == -1j * f('IIZZ')
|
|
178
|
+
assert cirq.XX(*cirq.LineQubit.range(1, 3)) * f('IXYZ') == 1j * f('IIZZ')
|
|
179
|
+
|
|
176
180
|
# Mixed types.
|
|
177
181
|
m = cirq.MutableDensePauliString
|
|
178
182
|
assert m('X') * m('Z') == -1j * m('Y')
|
|
@@ -187,6 +191,10 @@ def test_mul() -> None:
|
|
|
187
191
|
assert f('I') * f('III') == f('III')
|
|
188
192
|
assert f('X') * f('XXX') == f('IXX')
|
|
189
193
|
assert f('XXX') * f('X') == f('IXX')
|
|
194
|
+
assert f('X') * cirq.Y(cirq.LineQubit(2)) == f('XIY')
|
|
195
|
+
assert f('XY') * cirq.YY(*cirq.LineQubit.range(1, 3)) == f('XIY')
|
|
196
|
+
assert cirq.X(cirq.LineQubit(2)) * f('Y') == f('YIX')
|
|
197
|
+
assert cirq.XX(*cirq.LineQubit.range(1, 3)) * f('YX') == f('YIX')
|
|
190
198
|
|
|
191
199
|
with pytest.raises(TypeError):
|
|
192
200
|
_ = f('I') * object()
|
|
@@ -235,8 +243,15 @@ def test_imul() -> None:
|
|
|
235
243
|
p *= cirq.X(cirq.LineQubit(1))
|
|
236
244
|
assert p == m('IZI')
|
|
237
245
|
|
|
246
|
+
p *= cirq.ZZ(*cirq.LineQubit.range(1, 3))
|
|
247
|
+
assert p == m('IIZ')
|
|
248
|
+
|
|
238
249
|
with pytest.raises(ValueError, match='smaller than'):
|
|
239
250
|
p *= f('XXXXXXXXXXXX')
|
|
251
|
+
with pytest.raises(ValueError, match='smaller than'):
|
|
252
|
+
p *= cirq.X(cirq.LineQubit(3))
|
|
253
|
+
with pytest.raises(ValueError, match='smaller than'):
|
|
254
|
+
p *= cirq.XX(*cirq.LineQubit.range(2, 4))
|
|
240
255
|
with pytest.raises(TypeError):
|
|
241
256
|
p *= object()
|
|
242
257
|
|
|
@@ -507,6 +522,12 @@ def test_commutes() -> None:
|
|
|
507
522
|
assert cirq.commutes(f('IIIXII'), cirq.X(cirq.LineQubit(2)))
|
|
508
523
|
assert not cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(3)))
|
|
509
524
|
assert cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(2)))
|
|
525
|
+
assert cirq.commutes(f('IIIXII'), cirq.X(cirq.LineQubit(3)) ** 3)
|
|
526
|
+
assert cirq.commutes(f('IIIXII'), cirq.X(cirq.LineQubit(2)) ** 3)
|
|
527
|
+
assert not cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(3)) ** 3)
|
|
528
|
+
assert cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(2)) ** 3)
|
|
529
|
+
assert cirq.commutes(f('X'), cirq.Z(cirq.LineQubit(10)))
|
|
530
|
+
assert cirq.commutes(cirq.Z(cirq.LineQubit(10)), f('X'))
|
|
510
531
|
|
|
511
532
|
assert cirq.commutes(f('XX'), "test", default=NotImplemented) is NotImplemented
|
|
512
533
|
|
cirq/ops/diagonal_gate.py
CHANGED
|
@@ -20,7 +20,8 @@ passed as a list.
|
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
|
-
from
|
|
23
|
+
from collections.abc import Iterator, Sequence, Set
|
|
24
|
+
from typing import Any, TYPE_CHECKING
|
|
24
25
|
|
|
25
26
|
import numpy as np
|
|
26
27
|
import sympy
|
|
@@ -95,7 +96,7 @@ class DiagonalGate(raw_types.Gate):
|
|
|
95
96
|
def _is_parameterized_(self) -> bool:
|
|
96
97
|
return any(protocols.is_parameterized(angle) for angle in self._diag_angles_radians)
|
|
97
98
|
|
|
98
|
-
def _parameter_names_(self) ->
|
|
99
|
+
def _parameter_names_(self) -> Set[str]:
|
|
99
100
|
return {
|
|
100
101
|
name for angle in self._diag_angles_radians for name in protocols.parameter_names(angle)
|
|
101
102
|
}
|
cirq/ops/eigen_gate.py
CHANGED
|
@@ -18,8 +18,9 @@ import abc
|
|
|
18
18
|
import fractions
|
|
19
19
|
import math
|
|
20
20
|
import numbers
|
|
21
|
+
from collections.abc import Iterable, Set
|
|
21
22
|
from types import NotImplementedType
|
|
22
|
-
from typing import
|
|
23
|
+
from typing import Any, cast, NamedTuple, TYPE_CHECKING
|
|
23
24
|
|
|
24
25
|
import numpy as np
|
|
25
26
|
import sympy
|
|
@@ -341,16 +342,17 @@ class EigenGate(raw_types.Gate):
|
|
|
341
342
|
def _is_parameterized_(self) -> bool:
|
|
342
343
|
return protocols.is_parameterized(self._exponent)
|
|
343
344
|
|
|
344
|
-
def _parameter_names_(self) ->
|
|
345
|
+
def _parameter_names_(self) -> Set[str]:
|
|
345
346
|
return protocols.parameter_names(self._exponent)
|
|
346
347
|
|
|
347
348
|
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> EigenGate:
|
|
348
349
|
exponent = resolver.value_of(self._exponent, recursive)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
350
|
+
# Note that int/float checking is purposely done first,
|
|
351
|
+
# since numbers instance checking is somewhat slow.
|
|
352
|
+
if isinstance(exponent, (int, float)) or isinstance(exponent, numbers.Real): # noqa: SIM101
|
|
353
|
+
exponent = float(exponent)
|
|
354
|
+
elif isinstance(exponent, numbers.Complex):
|
|
355
|
+
raise ValueError(f'Complex exponent {exponent} not supported for EigenGate')
|
|
354
356
|
return self._with_exponent(exponent=exponent)
|
|
355
357
|
|
|
356
358
|
def _equal_up_to_global_phase_(self, other, atol):
|
cirq/ops/fourier_transform.py
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from collections.abc import Set
|
|
18
|
+
from typing import Any
|
|
18
19
|
|
|
19
20
|
import numpy as np
|
|
20
21
|
import sympy
|
|
@@ -163,7 +164,7 @@ class PhaseGradientGate(raw_types.Gate):
|
|
|
163
164
|
def _is_parameterized_(self) -> bool:
|
|
164
165
|
return cirq.is_parameterized(self.exponent)
|
|
165
166
|
|
|
166
|
-
def _parameter_names_(self) ->
|
|
167
|
+
def _parameter_names_(self) -> Set[str]:
|
|
167
168
|
return cirq.parameter_names(self.exponent)
|
|
168
169
|
|
|
169
170
|
def _resolve_parameters_(
|
|
@@ -107,9 +107,7 @@ def test_qft() -> None:
|
|
|
107
107
|
|
|
108
108
|
arr = np.array([[1, 1, 1, 1], [1, -1j, -1, 1j], [1, -1, 1, -1], [1, 1j, -1, -1j]]) / 2
|
|
109
109
|
np.testing.assert_allclose(
|
|
110
|
-
cirq.unitary(cirq.qft(*cirq.LineQubit.range(2)) ** -1),
|
|
111
|
-
arr, # type: ignore[arg-type]
|
|
112
|
-
atol=1e-8,
|
|
110
|
+
cirq.unitary(cirq.qft(*cirq.LineQubit.range(2)) ** -1), arr, atol=1e-8
|
|
113
111
|
)
|
|
114
112
|
|
|
115
113
|
for k in range(4):
|
|
@@ -121,7 +119,7 @@ def test_qft() -> None:
|
|
|
121
119
|
|
|
122
120
|
def test_inverse() -> None:
|
|
123
121
|
a, b, c = cirq.LineQubit.range(3)
|
|
124
|
-
assert cirq.qft(a, b, c, inverse=True) == cirq.qft(a, b, c) ** -1
|
|
122
|
+
assert cirq.qft(a, b, c, inverse=True) == cirq.qft(a, b, c) ** -1
|
|
125
123
|
assert cirq.qft(a, b, c, inverse=True, without_reverse=True) == cirq.inverse(
|
|
126
124
|
cirq.qft(a, b, c, without_reverse=True)
|
|
127
125
|
)
|
cirq/ops/fsim_gate.py
CHANGED
|
@@ -26,7 +26,8 @@ from __future__ import annotations
|
|
|
26
26
|
|
|
27
27
|
import cmath
|
|
28
28
|
import math
|
|
29
|
-
from
|
|
29
|
+
from collections.abc import Iterator, Set
|
|
30
|
+
from typing import Any
|
|
30
31
|
|
|
31
32
|
import numpy as np
|
|
32
33
|
import sympy
|
|
@@ -125,7 +126,7 @@ class FSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
125
126
|
def _is_parameterized_(self) -> bool:
|
|
126
127
|
return cirq.is_parameterized(self.theta) or cirq.is_parameterized(self.phi)
|
|
127
128
|
|
|
128
|
-
def _parameter_names_(self) ->
|
|
129
|
+
def _parameter_names_(self) -> Set[str]:
|
|
129
130
|
return cirq.parameter_names(self.theta) | cirq.parameter_names(self.phi)
|
|
130
131
|
|
|
131
132
|
def _has_unitary_(self):
|
cirq/ops/gate_operation.py
CHANGED
|
@@ -16,20 +16,12 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
+
import numbers
|
|
19
20
|
import re
|
|
20
21
|
import warnings
|
|
22
|
+
from collections.abc import Collection, Mapping, Sequence, Set
|
|
21
23
|
from types import NotImplementedType
|
|
22
|
-
from typing import
|
|
23
|
-
AbstractSet,
|
|
24
|
-
Any,
|
|
25
|
-
cast,
|
|
26
|
-
Collection,
|
|
27
|
-
Mapping,
|
|
28
|
-
Self,
|
|
29
|
-
Sequence,
|
|
30
|
-
TYPE_CHECKING,
|
|
31
|
-
TypeVar,
|
|
32
|
-
)
|
|
24
|
+
from typing import Any, cast, Self, TYPE_CHECKING, TypeVar
|
|
33
25
|
|
|
34
26
|
from cirq import ops, protocols, value
|
|
35
27
|
from cirq.ops import control_values as cv, gate_features, raw_types
|
|
@@ -269,7 +261,7 @@ class GateOperation(raw_types.Operation):
|
|
|
269
261
|
return getter()
|
|
270
262
|
return NotImplemented
|
|
271
263
|
|
|
272
|
-
def _parameter_names_(self) ->
|
|
264
|
+
def _parameter_names_(self) -> Set[str]:
|
|
273
265
|
getter = getattr(self.gate, '_parameter_names_', None)
|
|
274
266
|
if getter is not None:
|
|
275
267
|
return getter()
|
|
@@ -331,6 +323,25 @@ class GateOperation(raw_types.Operation):
|
|
|
331
323
|
def __rmul__(self, other: Any) -> Any:
|
|
332
324
|
return self.gate._rmul_with_qubits(self._qubits, other)
|
|
333
325
|
|
|
326
|
+
def __add__(self, other):
|
|
327
|
+
if not isinstance(other, (ops.Operation, numbers.Number)):
|
|
328
|
+
return NotImplemented
|
|
329
|
+
return 1 * self + other
|
|
330
|
+
|
|
331
|
+
def __radd__(self, other):
|
|
332
|
+
return other + 1 * self
|
|
333
|
+
|
|
334
|
+
def __sub__(self, other):
|
|
335
|
+
if not isinstance(other, (ops.Operation, numbers.Number)):
|
|
336
|
+
return NotImplemented
|
|
337
|
+
return 1 * self - other
|
|
338
|
+
|
|
339
|
+
def __rsub__(self, other):
|
|
340
|
+
return other + -self
|
|
341
|
+
|
|
342
|
+
def __neg__(self):
|
|
343
|
+
return -1 * self
|
|
344
|
+
|
|
334
345
|
def _qasm_(self, args: protocols.QasmArgs) -> str | None:
|
|
335
346
|
if isinstance(self.gate, ops.GlobalPhaseGate):
|
|
336
347
|
warnings.warn(
|
cirq/ops/gateset.py
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from
|
|
19
|
+
from collections.abc import Callable, Hashable, Iterable
|
|
20
|
+
from typing import Any, cast, TYPE_CHECKING
|
|
20
21
|
|
|
21
22
|
from cirq import protocols, value
|
|
22
23
|
from cirq.ops import global_phase_op, op_tree, raw_types
|
|
@@ -340,6 +341,7 @@ class Gateset:
|
|
|
340
341
|
self._unroll_circuit_op = unroll_circuit_op
|
|
341
342
|
self._instance_gate_families: dict[raw_types.Gate, GateFamily] = {}
|
|
342
343
|
self._type_gate_families: dict[type[raw_types.Gate], GateFamily] = {}
|
|
344
|
+
self._gate_families_with_tags: list[GateFamily] = []
|
|
343
345
|
self._gates_repr_str = ", ".join([_gate_str(g, repr) for g in gates])
|
|
344
346
|
unique_gate_list: list[GateFamily] = list(
|
|
345
347
|
dict.fromkeys(g if isinstance(g, GateFamily) else GateFamily(gate=g) for g in gates)
|
|
@@ -351,6 +353,12 @@ class Gateset:
|
|
|
351
353
|
self._instance_gate_families[g.gate] = g
|
|
352
354
|
else:
|
|
353
355
|
self._type_gate_families[g.gate] = g
|
|
356
|
+
else:
|
|
357
|
+
if isinstance(g.gate, raw_types.Gate):
|
|
358
|
+
self._gate_families_with_tags.append(g)
|
|
359
|
+
else:
|
|
360
|
+
# Instance checks are faster, so test them first.
|
|
361
|
+
self._gate_families_with_tags.insert(0, g)
|
|
354
362
|
self._unique_gate_list = unique_gate_list
|
|
355
363
|
self._gates = frozenset(unique_gate_list)
|
|
356
364
|
|
|
@@ -422,6 +430,7 @@ class Gateset:
|
|
|
422
430
|
g = item if isinstance(item, raw_types.Gate) else item.gate
|
|
423
431
|
assert g is not None, f'`item`: {item} must be a gate or have a valid `item.gate`'
|
|
424
432
|
|
|
433
|
+
# Check "type" based GateFamily since isinstance is fast
|
|
425
434
|
for gate_mro_type in type(g).mro():
|
|
426
435
|
if gate_mro_type in self._type_gate_families:
|
|
427
436
|
assert item in self._type_gate_families[gate_mro_type], (
|
|
@@ -430,6 +439,7 @@ class Gateset:
|
|
|
430
439
|
)
|
|
431
440
|
return True
|
|
432
441
|
|
|
442
|
+
# Check exact instance equality next
|
|
433
443
|
if g in self._instance_gate_families:
|
|
434
444
|
assert item in self._instance_gate_families[g], (
|
|
435
445
|
f"{item} instance matches {self._instance_gate_families[g]} but "
|
|
@@ -437,7 +447,17 @@ class Gateset:
|
|
|
437
447
|
)
|
|
438
448
|
return True
|
|
439
449
|
|
|
440
|
-
|
|
450
|
+
# Check other GateFamilies next
|
|
451
|
+
if any(item in gate_family for gate_family in self._gate_families_with_tags):
|
|
452
|
+
return True
|
|
453
|
+
|
|
454
|
+
# Lastly, do a final exhaustive check to make sure this is not equivalent
|
|
455
|
+
# to another type of gate. This will catch things like:
|
|
456
|
+
# cirq.XPowGate(exponent=0) in cirq.GateFamily(cirq.I)
|
|
457
|
+
return any(
|
|
458
|
+
item in gate_family
|
|
459
|
+
for gate_family in self._gates.difference(self._gate_families_with_tags)
|
|
460
|
+
)
|
|
441
461
|
|
|
442
462
|
def validate(self, circuit_or_optree: cirq.AbstractCircuit | op_tree.OP_TREE) -> bool:
|
|
443
463
|
"""Validates gates forming `circuit_or_optree` should be contained in Gateset.
|
cirq/ops/global_phase_op.py
CHANGED
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
|
+
from collections.abc import Collection, Sequence, Set
|
|
18
19
|
from types import NotImplementedType
|
|
19
|
-
from typing import
|
|
20
|
+
from typing import Any, cast
|
|
20
21
|
|
|
21
22
|
import numpy as np
|
|
22
23
|
import sympy
|
|
@@ -83,7 +84,7 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
83
84
|
def _is_parameterized_(self) -> bool:
|
|
84
85
|
return protocols.is_parameterized(self.coefficient)
|
|
85
86
|
|
|
86
|
-
def _parameter_names_(self) ->
|
|
87
|
+
def _parameter_names_(self) -> Set[str]:
|
|
87
88
|
return protocols.parameter_names(self.coefficient)
|
|
88
89
|
|
|
89
90
|
def _resolve_parameters_(
|
cirq/ops/greedy_qubit_manager.py
CHANGED
cirq/ops/identity.py
CHANGED
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
18
|
import numbers
|
|
19
|
+
from collections.abc import Sequence
|
|
19
20
|
from types import NotImplementedType
|
|
20
|
-
from typing import Any,
|
|
21
|
+
from typing import Any, TYPE_CHECKING
|
|
21
22
|
|
|
22
23
|
import numpy as np
|
|
23
24
|
import sympy
|
cirq/ops/kraus_channel.py
CHANGED
cirq/ops/linear_combinations.py
CHANGED
|
@@ -16,7 +16,8 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import numbers
|
|
18
18
|
from collections import defaultdict
|
|
19
|
-
from
|
|
19
|
+
from collections.abc import Iterable, Mapping, Set
|
|
20
|
+
from typing import Any, TYPE_CHECKING, Union
|
|
20
21
|
|
|
21
22
|
import numpy as np
|
|
22
23
|
import sympy
|
|
@@ -136,7 +137,7 @@ class LinearCombinationOfGates(value.LinearDict[raw_types.Gate]):
|
|
|
136
137
|
def _is_parameterized_(self) -> bool:
|
|
137
138
|
return any(protocols.is_parameterized(item) for item in self.items())
|
|
138
139
|
|
|
139
|
-
def _parameter_names_(self) ->
|
|
140
|
+
def _parameter_names_(self) -> Set[str]:
|
|
140
141
|
return {name for item in self.items() for name in protocols.parameter_names(item)}
|
|
141
142
|
|
|
142
143
|
def _resolve_parameters_(
|
|
@@ -253,7 +254,7 @@ class LinearCombinationOfOperations(value.LinearDict[raw_types.Operation]):
|
|
|
253
254
|
def _is_parameterized_(self) -> bool:
|
|
254
255
|
return any(protocols.is_parameterized(item) for item in self.items())
|
|
255
256
|
|
|
256
|
-
def _parameter_names_(self) ->
|
|
257
|
+
def _parameter_names_(self) -> Set[str]:
|
|
257
258
|
return {name for item in self.items() for name in protocols.parameter_names(item)}
|
|
258
259
|
|
|
259
260
|
def _resolve_parameters_(
|
|
@@ -742,14 +743,12 @@ class PauliSum:
|
|
|
742
743
|
return len(self._linear_dict)
|
|
743
744
|
|
|
744
745
|
def __iadd__(self, other):
|
|
746
|
+
if isinstance(other, raw_types.Operation):
|
|
747
|
+
other = pauli_string._try_interpret_as_pauli_string(other)
|
|
745
748
|
if isinstance(other, numbers.Complex):
|
|
746
749
|
other = PauliSum.from_pauli_strings([PauliString(coefficient=other)])
|
|
747
750
|
elif isinstance(other, PauliString):
|
|
748
751
|
other = PauliSum.from_pauli_strings([other])
|
|
749
|
-
elif isinstance(other, raw_types.Operation) and isinstance(
|
|
750
|
-
other.gate, identity.IdentityGate
|
|
751
|
-
):
|
|
752
|
-
other = PauliSum.from_pauli_strings([PauliString()])
|
|
753
752
|
|
|
754
753
|
if not isinstance(other, PauliSum):
|
|
755
754
|
return NotImplemented
|
|
@@ -758,10 +757,9 @@ class PauliSum:
|
|
|
758
757
|
return self
|
|
759
758
|
|
|
760
759
|
def __add__(self, other):
|
|
761
|
-
if not isinstance(other, (numbers.Complex, PauliString, PauliSum, raw_types.Operation)):
|
|
762
|
-
return NotImplemented
|
|
763
760
|
result = self.copy()
|
|
764
|
-
result
|
|
761
|
+
if result.__iadd__(other) is NotImplemented:
|
|
762
|
+
return NotImplemented
|
|
765
763
|
return result
|
|
766
764
|
|
|
767
765
|
def __radd__(self, other):
|
|
@@ -771,14 +769,12 @@ class PauliSum:
|
|
|
771
769
|
return -self.__sub__(other)
|
|
772
770
|
|
|
773
771
|
def __isub__(self, other):
|
|
772
|
+
if isinstance(other, raw_types.Operation):
|
|
773
|
+
other = pauli_string._try_interpret_as_pauli_string(other)
|
|
774
774
|
if isinstance(other, numbers.Complex):
|
|
775
775
|
other = PauliSum.from_pauli_strings([PauliString(coefficient=other)])
|
|
776
776
|
elif isinstance(other, PauliString):
|
|
777
777
|
other = PauliSum.from_pauli_strings([other])
|
|
778
|
-
elif isinstance(other, raw_types.Operation) and isinstance(
|
|
779
|
-
other.gate, identity.IdentityGate
|
|
780
|
-
):
|
|
781
|
-
other = PauliSum.from_pauli_strings([PauliString()])
|
|
782
778
|
|
|
783
779
|
if not isinstance(other, PauliSum):
|
|
784
780
|
return NotImplemented
|
|
@@ -787,10 +783,9 @@ class PauliSum:
|
|
|
787
783
|
return self
|
|
788
784
|
|
|
789
785
|
def __sub__(self, other):
|
|
790
|
-
if not isinstance(other, (numbers.Complex, PauliString, PauliSum, raw_types.Operation)):
|
|
791
|
-
return NotImplemented
|
|
792
786
|
result = self.copy()
|
|
793
|
-
result
|
|
787
|
+
if result.__isub__(other) is NotImplemented:
|
|
788
|
+
return NotImplemented
|
|
794
789
|
return result
|
|
795
790
|
|
|
796
791
|
def __neg__(self):
|