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/__init__.py
CHANGED
|
@@ -509,6 +509,7 @@ from cirq.study import (
|
|
|
509
509
|
flatten_with_sweep as flatten_with_sweep,
|
|
510
510
|
ResultDict as ResultDict,
|
|
511
511
|
Linspace as Linspace,
|
|
512
|
+
list_of_dicts_to_zip as list_of_dicts_to_zip,
|
|
512
513
|
ListSweep as ListSweep,
|
|
513
514
|
ParamDictType as ParamDictType,
|
|
514
515
|
ParamMappingType as ParamMappingType,
|
cirq/_compat.py
CHANGED
|
@@ -20,15 +20,16 @@ import contextlib
|
|
|
20
20
|
import contextvars
|
|
21
21
|
import dataclasses
|
|
22
22
|
import functools
|
|
23
|
-
import importlib
|
|
23
|
+
import importlib.util
|
|
24
24
|
import inspect
|
|
25
25
|
import os
|
|
26
26
|
import re
|
|
27
27
|
import sys
|
|
28
28
|
import traceback
|
|
29
29
|
import warnings
|
|
30
|
+
from collections.abc import Callable, Iterator
|
|
30
31
|
from types import ModuleType
|
|
31
|
-
from typing import Any,
|
|
32
|
+
from typing import Any, overload, TypeVar
|
|
32
33
|
|
|
33
34
|
import numpy as np
|
|
34
35
|
import pandas as pd
|
cirq/_compat_test.py
CHANGED
|
@@ -25,9 +25,10 @@ import sys
|
|
|
25
25
|
import traceback
|
|
26
26
|
import types
|
|
27
27
|
import warnings
|
|
28
|
+
from collections.abc import Callable
|
|
28
29
|
from importlib.machinery import ModuleSpec
|
|
29
30
|
from types import ModuleType
|
|
30
|
-
from typing import Any
|
|
31
|
+
from typing import Any
|
|
31
32
|
from unittest import mock
|
|
32
33
|
|
|
33
34
|
import duet
|
|
@@ -159,7 +160,7 @@ def test_deprecated_with_name():
|
|
|
159
160
|
|
|
160
161
|
|
|
161
162
|
def test_deprecated_with_property():
|
|
162
|
-
class AClass
|
|
163
|
+
class AClass:
|
|
163
164
|
def __init__(self, a):
|
|
164
165
|
self.a = a
|
|
165
166
|
|
|
@@ -554,11 +555,11 @@ def _import_deprecated_same_name_in_earlier_subtree():
|
|
|
554
555
|
|
|
555
556
|
|
|
556
557
|
def _import_top_level_deprecated():
|
|
557
|
-
import
|
|
558
|
+
import numpy.random
|
|
558
559
|
|
|
559
|
-
from cirq.testing._compat_test_data.
|
|
560
|
+
from cirq.testing._compat_test_data.fake_numpy import random # type: ignore
|
|
560
561
|
|
|
561
|
-
assert
|
|
562
|
+
assert random.normal is numpy.random.normal
|
|
562
563
|
|
|
563
564
|
|
|
564
565
|
def _repeated_import_path():
|
|
@@ -611,9 +612,9 @@ _fake_ops_deprecation_msg = [
|
|
|
611
612
|
|
|
612
613
|
|
|
613
614
|
# see cirq_compat_test_data/__init__.py for the setup code
|
|
614
|
-
|
|
615
|
-
f'{old_parent}.
|
|
616
|
-
'Use
|
|
615
|
+
_fake_numpy_deprecation_msg = [
|
|
616
|
+
f'{old_parent}.fake_numpy was used but is deprecated',
|
|
617
|
+
'Use numpy instead',
|
|
617
618
|
] + _deprecation_origin
|
|
618
619
|
|
|
619
620
|
# see cirq_compat_test_data/__init__.py for the setup code
|
|
@@ -686,7 +687,7 @@ def run_in_subprocess(test_func, *args):
|
|
|
686
687
|
(_import_parent_use_constant_from_deprecated_module_attribute, [_fake_a_deprecation_msg]),
|
|
687
688
|
(_import_deprecated_sub_use_constant, [_fake_a_deprecation_msg]),
|
|
688
689
|
(_import_deprecated_same_name_in_earlier_subtree, [_fake_a_deprecation_msg]),
|
|
689
|
-
(_import_top_level_deprecated, [
|
|
690
|
+
(_import_top_level_deprecated, [_fake_numpy_deprecation_msg]),
|
|
690
691
|
(_from_deprecated_import_sub_of_sub, [_fake_a_deprecation_msg]),
|
|
691
692
|
(_repeated_import_path, [_repeated_child_deprecation_msg]),
|
|
692
693
|
(_type_repr_in_deprecated_module, [_fake_a_deprecation_msg]),
|
|
@@ -746,7 +747,7 @@ def test_metadata_search_path():
|
|
|
746
747
|
run_in_subprocess(_test_metadata_search_path_inner)
|
|
747
748
|
|
|
748
749
|
|
|
749
|
-
def _test_metadata_search_path_inner():
|
|
750
|
+
def _test_metadata_search_path_inner():
|
|
750
751
|
# initialize the DeprecatedModuleFinders
|
|
751
752
|
assert importlib.metadata.metadata('numpy')
|
|
752
753
|
|
|
@@ -855,13 +856,13 @@ def test_new_module_is_top_level():
|
|
|
855
856
|
|
|
856
857
|
|
|
857
858
|
def _test_new_module_is_top_level_inner():
|
|
858
|
-
|
|
859
|
-
import time
|
|
859
|
+
from numpy.random import normal
|
|
860
860
|
|
|
861
|
-
#
|
|
862
|
-
|
|
861
|
+
# sets up the DeprecationFinders
|
|
862
|
+
import cirq.testing._compat_test_data # noqa: F401
|
|
863
863
|
|
|
864
|
-
|
|
864
|
+
# imports a top level new module replacing deprecated module
|
|
865
|
+
assert normal is importlib.import_module('numpy').random.normal
|
|
865
866
|
|
|
866
867
|
|
|
867
868
|
def test_import_deprecated_with_no_attribute():
|
cirq/_doc.py
CHANGED
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
|
-
from typing import
|
|
18
|
+
from typing import TypeVar
|
|
19
19
|
|
|
20
|
+
T = TypeVar('T')
|
|
20
21
|
RECORDED_CONST_DOCS: dict[int, str] = {}
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
def document(value:
|
|
24
|
+
def document(value: T, doc_string: str = '') -> T:
|
|
24
25
|
"""Stores documentation details about the given value.
|
|
25
26
|
|
|
26
27
|
This method is used to associate a docstring with global constants. It is
|
|
@@ -64,7 +65,7 @@ def document(value: Any, doc_string: str = ''):
|
|
|
64
65
|
_DOC_PRIVATE = "_tf_docs_doc_private"
|
|
65
66
|
|
|
66
67
|
|
|
67
|
-
def doc_private(obj):
|
|
68
|
+
def doc_private(obj: T) -> T:
|
|
68
69
|
"""A decorator: Generates docs for private methods/functions.
|
|
69
70
|
|
|
70
71
|
For example:
|
cirq/_import.py
CHANGED
|
@@ -16,12 +16,13 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import importlib
|
|
18
18
|
import sys
|
|
19
|
+
from collections.abc import Callable
|
|
19
20
|
from contextlib import contextmanager
|
|
20
21
|
from importlib import abc
|
|
21
22
|
from importlib.abc import Loader
|
|
22
23
|
from importlib.machinery import ModuleSpec
|
|
23
24
|
from types import ModuleType
|
|
24
|
-
from typing import Any,
|
|
25
|
+
from typing import Any, cast
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
class InstrumentedFinder(abc.MetaPathFinder):
|
cirq/_version.py
CHANGED
cirq/_version_test.py
CHANGED
cirq/circuits/circuit.py
CHANGED
|
@@ -27,24 +27,18 @@ import html
|
|
|
27
27
|
import itertools
|
|
28
28
|
import math
|
|
29
29
|
from collections import defaultdict
|
|
30
|
-
from
|
|
31
|
-
from typing import (
|
|
32
|
-
AbstractSet,
|
|
33
|
-
Any,
|
|
30
|
+
from collections.abc import (
|
|
34
31
|
Callable,
|
|
35
|
-
cast,
|
|
36
32
|
Hashable,
|
|
37
33
|
Iterable,
|
|
38
34
|
Iterator,
|
|
39
35
|
Mapping,
|
|
40
36
|
MutableSequence,
|
|
41
|
-
overload,
|
|
42
|
-
Self,
|
|
43
37
|
Sequence,
|
|
44
|
-
|
|
45
|
-
TypeVar,
|
|
46
|
-
Union,
|
|
38
|
+
Set,
|
|
47
39
|
)
|
|
40
|
+
from types import NotImplementedType
|
|
41
|
+
from typing import Any, cast, overload, Self, TYPE_CHECKING, TypeVar, Union
|
|
48
42
|
|
|
49
43
|
import networkx
|
|
50
44
|
import numpy as np
|
|
@@ -1341,7 +1335,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1341
1335
|
protocols.is_parameterized(tag) for tag in self.tags
|
|
1342
1336
|
)
|
|
1343
1337
|
|
|
1344
|
-
def _parameter_names_(self) ->
|
|
1338
|
+
def _parameter_names_(self) -> Set[str]:
|
|
1345
1339
|
op_params = {name for op in self.all_operations() for name in protocols.parameter_names(op)}
|
|
1346
1340
|
tag_params = {name for tag in self.tags for name in protocols.parameter_names(tag)}
|
|
1347
1341
|
return op_params | tag_params
|
|
@@ -1666,8 +1660,14 @@ class AbstractCircuit(abc.ABC):
|
|
|
1666
1660
|
)
|
|
1667
1661
|
|
|
1668
1662
|
def _control_keys_(self) -> frozenset[cirq.MeasurementKey]:
|
|
1669
|
-
|
|
1670
|
-
|
|
1663
|
+
measures: set[cirq.MeasurementKey] = set()
|
|
1664
|
+
controls: set[cirq.MeasurementKey] = set()
|
|
1665
|
+
for op in self.all_operations():
|
|
1666
|
+
# Only require keys that haven't already been measured earlier
|
|
1667
|
+
controls.update(k for k in protocols.control_keys(op) if k not in measures)
|
|
1668
|
+
# Record any measurement keys produced by this op
|
|
1669
|
+
measures.update(protocols.measurement_key_objs(op))
|
|
1670
|
+
return frozenset(controls)
|
|
1671
1671
|
|
|
1672
1672
|
|
|
1673
1673
|
def _overlap_collision_time(
|
|
@@ -1839,7 +1839,7 @@ class Circuit(AbstractCircuit):
|
|
|
1839
1839
|
self._frozen: cirq.FrozenCircuit | None = None
|
|
1840
1840
|
self._is_measurement: bool | None = None
|
|
1841
1841
|
self._is_parameterized: bool | None = None
|
|
1842
|
-
self._parameter_names:
|
|
1842
|
+
self._parameter_names: Set[str] | None = None
|
|
1843
1843
|
if not contents:
|
|
1844
1844
|
return
|
|
1845
1845
|
flattened_contents = tuple(ops.flatten_to_ops_or_moments(contents))
|
|
@@ -1948,7 +1948,7 @@ class Circuit(AbstractCircuit):
|
|
|
1948
1948
|
self._is_parameterized = super()._is_parameterized_()
|
|
1949
1949
|
return self._is_parameterized
|
|
1950
1950
|
|
|
1951
|
-
def _parameter_names_(self) ->
|
|
1951
|
+
def _parameter_names_(self) -> Set[str]:
|
|
1952
1952
|
if self._parameter_names is None:
|
|
1953
1953
|
self._parameter_names = super()._parameter_names_()
|
|
1954
1954
|
return self._parameter_names
|
|
@@ -3002,13 +3002,15 @@ def get_earliest_accommodating_moment_index(
|
|
|
3002
3002
|
mop_index = last_conflict + 1
|
|
3003
3003
|
|
|
3004
3004
|
# Update our dicts with data from this `mop` placement. Note `mop_index` will always be greater
|
|
3005
|
-
# than the existing value for
|
|
3005
|
+
# than the existing value for qubits and measurement keys, by construction.
|
|
3006
3006
|
for qubit in mop_qubits:
|
|
3007
3007
|
qubit_indices[qubit] = mop_index
|
|
3008
3008
|
for key in mop_mkeys:
|
|
3009
3009
|
mkey_indices[key] = mop_index
|
|
3010
|
+
# For control keys, keep the maximum moment index seen so far because ops with the same control
|
|
3011
|
+
# keys can commute past each other.
|
|
3010
3012
|
for key in mop_ckeys:
|
|
3011
|
-
ckey_indices[key] = mop_index
|
|
3013
|
+
ckey_indices[key] = max(mop_index, ckey_indices.get(key, -1))
|
|
3012
3014
|
|
|
3013
3015
|
return mop_index
|
|
3014
3016
|
|
|
@@ -22,8 +22,9 @@ component operations in order, including any nested CircuitOperations.
|
|
|
22
22
|
from __future__ import annotations
|
|
23
23
|
|
|
24
24
|
import math
|
|
25
|
+
from collections.abc import Callable, Iterator, Mapping, Sequence
|
|
25
26
|
from functools import cached_property
|
|
26
|
-
from typing import Any,
|
|
27
|
+
from typing import Any, cast, TYPE_CHECKING, TypeAlias
|
|
27
28
|
|
|
28
29
|
import numpy as np
|
|
29
30
|
import sympy
|
|
@@ -1253,22 +1253,27 @@ def test_repeat_until_protocols() -> None:
|
|
|
1253
1253
|
# Ensure the _repeat_until has been mapped, the measurement has been mapped to the same key,
|
|
1254
1254
|
# and the control keys of the subcircuit is empty (because the control key of the condition is
|
|
1255
1255
|
# bound to the measurement).
|
|
1256
|
+
assert scoped._mapped_repeat_until is not None
|
|
1256
1257
|
assert scoped._mapped_repeat_until.keys == (cirq.MeasurementKey('a', ('0',)),)
|
|
1257
1258
|
assert cirq.measurement_key_objs(scoped) == {cirq.MeasurementKey('a', ('0',))}
|
|
1258
1259
|
assert not cirq.control_keys(scoped)
|
|
1259
1260
|
mapped = cirq.with_measurement_key_mapping(scoped, {'a': 'b'})
|
|
1261
|
+
assert mapped._mapped_repeat_until is not None
|
|
1260
1262
|
assert mapped._mapped_repeat_until.keys == (cirq.MeasurementKey('b', ('0',)),)
|
|
1261
1263
|
assert cirq.measurement_key_objs(mapped) == {cirq.MeasurementKey('b', ('0',))}
|
|
1262
1264
|
assert not cirq.control_keys(mapped)
|
|
1263
1265
|
prefixed = cirq.with_key_path_prefix(mapped, ('1',))
|
|
1266
|
+
assert prefixed._mapped_repeat_until is not None
|
|
1264
1267
|
assert prefixed._mapped_repeat_until.keys == (cirq.MeasurementKey('b', ('1', '0')),)
|
|
1265
1268
|
assert cirq.measurement_key_objs(prefixed) == {cirq.MeasurementKey('b', ('1', '0'))}
|
|
1266
1269
|
assert not cirq.control_keys(prefixed)
|
|
1267
1270
|
setpath = cirq.with_key_path(prefixed, ('2',))
|
|
1271
|
+
assert setpath._mapped_repeat_until is not None
|
|
1268
1272
|
assert setpath._mapped_repeat_until.keys == (cirq.MeasurementKey('b', ('2',)),)
|
|
1269
1273
|
assert cirq.measurement_key_objs(setpath) == {cirq.MeasurementKey('b', ('2',))}
|
|
1270
1274
|
assert not cirq.control_keys(setpath)
|
|
1271
1275
|
resolved = cirq.resolve_parameters(setpath, {'p': 1})
|
|
1276
|
+
assert resolved._mapped_repeat_until is not None
|
|
1272
1277
|
assert resolved._mapped_repeat_until.keys == (cirq.MeasurementKey('b', ('2',)),)
|
|
1273
1278
|
assert cirq.measurement_key_objs(resolved) == {cirq.MeasurementKey('b', ('2',))}
|
|
1274
1279
|
assert not cirq.control_keys(resolved)
|
|
@@ -1324,3 +1329,17 @@ def test_has_unitary_protocol_returns_true_if_all_params_resolve() -> None:
|
|
|
1324
1329
|
exp = sympy.Symbol('exp')
|
|
1325
1330
|
op = cirq.CircuitOperation(cirq.FrozenCircuit(cirq.X(q) ** exp), param_resolver={exp: 0.5})
|
|
1326
1331
|
assert protocols.has_unitary(op)
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
def test_control_keys_respects_internal_measurement_order() -> None:
|
|
1335
|
+
q = cirq.LineQubit(0)
|
|
1336
|
+
|
|
1337
|
+
# Control BEFORE measurement inside the subcircuit: external key required
|
|
1338
|
+
fc_before = cirq.FrozenCircuit(cirq.X(q).with_classical_controls('a'), cirq.measure(q, key='a'))
|
|
1339
|
+
op_before = cirq.CircuitOperation(fc_before)
|
|
1340
|
+
assert cirq.control_keys(op_before) == {cirq.MeasurementKey('a')}
|
|
1341
|
+
|
|
1342
|
+
# Measurement BEFORE control inside the subcircuit: no external key required
|
|
1343
|
+
fc_after = cirq.FrozenCircuit(cirq.measure(q, key='a'), cirq.X(q).with_classical_controls('a'))
|
|
1344
|
+
op_after = cirq.CircuitOperation(fc_after)
|
|
1345
|
+
assert cirq.control_keys(op_after) == set()
|
cirq/circuits/circuit_test.py
CHANGED
|
@@ -18,8 +18,8 @@ import itertools
|
|
|
18
18
|
import os
|
|
19
19
|
import time
|
|
20
20
|
from collections import defaultdict
|
|
21
|
+
from collections.abc import Iterator, Sequence
|
|
21
22
|
from random import randint, random, randrange, sample
|
|
22
|
-
from typing import Iterator, Sequence
|
|
23
23
|
|
|
24
24
|
import numpy as np
|
|
25
25
|
import pytest
|
|
@@ -208,6 +208,24 @@ def test_append_control_key() -> None:
|
|
|
208
208
|
assert len(c) == 1
|
|
209
209
|
|
|
210
210
|
|
|
211
|
+
def test_append_control_key_before_measure() -> None:
|
|
212
|
+
c = cirq.Circuit()
|
|
213
|
+
q1, q2 = cirq.LineQubit.range(2)
|
|
214
|
+
c.append(cirq.X(q1))
|
|
215
|
+
c.append(cirq.X(q1))
|
|
216
|
+
c.append(cirq.X(q1).with_classical_controls('a'))
|
|
217
|
+
c.append(cirq.X(q2).with_classical_controls('a'))
|
|
218
|
+
c.append(cirq.measure(q2, key='a'))
|
|
219
|
+
assert c == cirq.Circuit(
|
|
220
|
+
[
|
|
221
|
+
cirq.Moment(cirq.X(q1), cirq.X(q2).with_classical_controls('a')),
|
|
222
|
+
cirq.Moment(cirq.X(q1)),
|
|
223
|
+
cirq.Moment(cirq.X(q1).with_classical_controls('a')),
|
|
224
|
+
cirq.Moment(cirq.measure(q2, key='a')),
|
|
225
|
+
]
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
|
|
211
229
|
def test_append_multiple() -> None:
|
|
212
230
|
a = cirq.NamedQubit('a')
|
|
213
231
|
b = cirq.NamedQubit('b')
|
|
@@ -338,20 +356,21 @@ def test_add_op_tree(circuit_cls) -> None:
|
|
|
338
356
|
|
|
339
357
|
|
|
340
358
|
@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit])
|
|
341
|
-
|
|
359
|
+
@pytest.mark.parametrize('gate', [cirq.X, cirq.H])
|
|
360
|
+
def test_radd_op_tree(circuit_cls, gate) -> None:
|
|
342
361
|
a = cirq.NamedQubit('a')
|
|
343
362
|
b = cirq.NamedQubit('b')
|
|
344
363
|
|
|
345
364
|
c = circuit_cls()
|
|
346
|
-
assert [
|
|
365
|
+
assert [gate(a), cirq.Y(b)] + c == circuit_cls([cirq.Moment([gate(a), cirq.Y(b)])])
|
|
347
366
|
|
|
348
|
-
assert
|
|
349
|
-
assert [
|
|
350
|
-
assert [[[
|
|
351
|
-
assert (
|
|
352
|
-
assert (
|
|
367
|
+
assert gate(a) + c == circuit_cls(gate(a))
|
|
368
|
+
assert [gate(a)] + c == circuit_cls(gate(a))
|
|
369
|
+
assert [[[gate(a)], []]] + c == circuit_cls(gate(a))
|
|
370
|
+
assert (gate(a),) + c == circuit_cls(gate(a))
|
|
371
|
+
assert (gate(a) for _ in range(1)) + c == circuit_cls(gate(a))
|
|
353
372
|
with pytest.raises(AttributeError):
|
|
354
|
-
_ =
|
|
373
|
+
_ = gate + c
|
|
355
374
|
with pytest.raises(TypeError):
|
|
356
375
|
_ = 0 + c
|
|
357
376
|
|
|
@@ -362,9 +381,9 @@ def test_radd_op_tree(circuit_cls) -> None:
|
|
|
362
381
|
else:
|
|
363
382
|
d = cirq.Circuit()
|
|
364
383
|
d.append(cirq.Y(b))
|
|
365
|
-
assert [
|
|
366
|
-
assert cirq.Moment([
|
|
367
|
-
[cirq.Moment([
|
|
384
|
+
assert [gate(a)] + d == circuit_cls([cirq.Moment([gate(a)]), cirq.Moment([cirq.Y(b)])])
|
|
385
|
+
assert cirq.Moment([gate(a)]) + d == circuit_cls(
|
|
386
|
+
[cirq.Moment([gate(a)]), cirq.Moment([cirq.Y(b)])]
|
|
368
387
|
)
|
|
369
388
|
|
|
370
389
|
|
cirq/circuits/frozen_circuit.py
CHANGED
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
+
from collections.abc import Hashable, Iterable, Iterator, Sequence, Set
|
|
19
20
|
from functools import cached_property
|
|
20
21
|
from types import NotImplementedType
|
|
21
|
-
from typing import
|
|
22
|
+
from typing import TYPE_CHECKING
|
|
22
23
|
|
|
23
24
|
from cirq import _compat, protocols
|
|
24
25
|
from cirq.circuits import AbstractCircuit, Alignment, Circuit
|
|
@@ -172,7 +173,7 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
172
173
|
return super()._is_parameterized_()
|
|
173
174
|
|
|
174
175
|
@_compat.cached_method
|
|
175
|
-
def _parameter_names_(self) ->
|
|
176
|
+
def _parameter_names_(self) -> Set[str]:
|
|
176
177
|
return super()._parameter_names_()
|
|
177
178
|
|
|
178
179
|
def _measurement_key_names_(self) -> frozenset[str]:
|
cirq/circuits/moment.py
CHANGED
|
@@ -17,22 +17,10 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import itertools
|
|
20
|
+
from collections.abc import Callable, Hashable, Iterable, Iterator, Mapping, Sequence, Set
|
|
20
21
|
from functools import cached_property
|
|
21
22
|
from types import NotImplementedType
|
|
22
|
-
from typing import
|
|
23
|
-
AbstractSet,
|
|
24
|
-
Any,
|
|
25
|
-
Callable,
|
|
26
|
-
cast,
|
|
27
|
-
Hashable,
|
|
28
|
-
Iterable,
|
|
29
|
-
Iterator,
|
|
30
|
-
Mapping,
|
|
31
|
-
overload,
|
|
32
|
-
Self,
|
|
33
|
-
Sequence,
|
|
34
|
-
TYPE_CHECKING,
|
|
35
|
-
)
|
|
23
|
+
from typing import Any, cast, overload, Self, TYPE_CHECKING
|
|
36
24
|
|
|
37
25
|
import numpy as np
|
|
38
26
|
|
|
@@ -307,7 +295,7 @@ class Moment:
|
|
|
307
295
|
return any(protocols.is_parameterized(op) for op in self)
|
|
308
296
|
|
|
309
297
|
@_compat.cached_method()
|
|
310
|
-
def _parameter_names_(self) ->
|
|
298
|
+
def _parameter_names_(self) -> Set[str]:
|
|
311
299
|
return {name for op in self for name in protocols.parameter_names(op)}
|
|
312
300
|
|
|
313
301
|
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> cirq.Moment:
|
|
@@ -18,7 +18,8 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import abc
|
|
20
20
|
from collections import defaultdict
|
|
21
|
-
from
|
|
21
|
+
from collections.abc import Callable, Iterable, Sequence
|
|
22
|
+
from typing import cast, TYPE_CHECKING
|
|
22
23
|
|
|
23
24
|
from cirq import ops
|
|
24
25
|
|
cirq/circuits/qasm_output.py
CHANGED
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import re
|
|
20
|
-
from
|
|
20
|
+
from collections.abc import Callable, Iterator, Sequence, Set
|
|
21
|
+
from typing import TYPE_CHECKING
|
|
21
22
|
|
|
22
23
|
import numpy as np
|
|
24
|
+
import sympy
|
|
23
25
|
|
|
24
26
|
from cirq import linalg, ops, protocols, value
|
|
27
|
+
from cirq._compat import proper_repr
|
|
25
28
|
|
|
26
29
|
if TYPE_CHECKING:
|
|
27
30
|
import cirq
|
|
@@ -29,7 +32,7 @@ if TYPE_CHECKING:
|
|
|
29
32
|
|
|
30
33
|
@value.value_equality(approximate=True)
|
|
31
34
|
class QasmUGate(ops.Gate):
|
|
32
|
-
def __init__(self, theta, phi, lmda) -> None:
|
|
35
|
+
def __init__(self, theta: cirq.TParamVal, phi: cirq.TParamVal, lmda: cirq.TParamVal) -> None:
|
|
33
36
|
"""A QASM gate representing any single qubit unitary with a series of
|
|
34
37
|
three rotations, Z, Y, and Z.
|
|
35
38
|
|
|
@@ -40,9 +43,9 @@ class QasmUGate(ops.Gate):
|
|
|
40
43
|
phi: Half turns to rotate about Z (applied last).
|
|
41
44
|
lmda: Half turns to rotate about Z (applied first).
|
|
42
45
|
"""
|
|
43
|
-
self.lmda = lmda % 2
|
|
44
46
|
self.theta = theta % 2
|
|
45
47
|
self.phi = phi % 2
|
|
48
|
+
self.lmda = lmda % 2
|
|
46
49
|
|
|
47
50
|
def _num_qubits_(self) -> int:
|
|
48
51
|
return 1
|
|
@@ -53,7 +56,28 @@ class QasmUGate(ops.Gate):
|
|
|
53
56
|
return QasmUGate(rotation / np.pi, post_phase / np.pi, pre_phase / np.pi)
|
|
54
57
|
|
|
55
58
|
def _has_unitary_(self):
|
|
56
|
-
return
|
|
59
|
+
return not self._is_parameterized_()
|
|
60
|
+
|
|
61
|
+
def _is_parameterized_(self) -> bool:
|
|
62
|
+
return (
|
|
63
|
+
protocols.is_parameterized(self.theta)
|
|
64
|
+
or protocols.is_parameterized(self.phi)
|
|
65
|
+
or protocols.is_parameterized(self.lmda)
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def _parameter_names_(self) -> Set[str]:
|
|
69
|
+
return (
|
|
70
|
+
protocols.parameter_names(self.theta)
|
|
71
|
+
| protocols.parameter_names(self.phi)
|
|
72
|
+
| protocols.parameter_names(self.lmda)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> QasmUGate:
|
|
76
|
+
return QasmUGate(
|
|
77
|
+
protocols.resolve_parameters(self.theta, resolver, recursive),
|
|
78
|
+
protocols.resolve_parameters(self.phi, resolver, recursive),
|
|
79
|
+
protocols.resolve_parameters(self.lmda, resolver, recursive),
|
|
80
|
+
)
|
|
57
81
|
|
|
58
82
|
def _qasm_(self, qubits: tuple[cirq.Qid, ...], args: cirq.QasmArgs) -> str:
|
|
59
83
|
args.validate_version('2.0', '3.0')
|
|
@@ -68,17 +92,22 @@ class QasmUGate(ops.Gate):
|
|
|
68
92
|
def __repr__(self) -> str:
|
|
69
93
|
return (
|
|
70
94
|
f'cirq.circuits.qasm_output.QasmUGate('
|
|
71
|
-
f'theta={self.theta
|
|
72
|
-
f'phi={self.phi
|
|
73
|
-
f'lmda={self.lmda})'
|
|
95
|
+
f'theta={proper_repr(self.theta)}, '
|
|
96
|
+
f'phi={proper_repr(self.phi)}, '
|
|
97
|
+
f'lmda={proper_repr(self.lmda)})'
|
|
74
98
|
)
|
|
75
99
|
|
|
76
100
|
def _decompose_(self, qubits):
|
|
101
|
+
def mul_pi(x):
|
|
102
|
+
return x * (sympy.pi if protocols.is_parameterized(x) else np.pi)
|
|
103
|
+
|
|
77
104
|
q = qubits[0]
|
|
105
|
+
phase_correction_half_turns = (self.phi + self.lmda) / 2
|
|
78
106
|
return [
|
|
79
|
-
ops.rz(self.lmda
|
|
80
|
-
ops.ry(self.theta
|
|
81
|
-
ops.rz(self.phi
|
|
107
|
+
ops.rz(mul_pi(self.lmda)).on(q),
|
|
108
|
+
ops.ry(mul_pi(self.theta)).on(q),
|
|
109
|
+
ops.rz(mul_pi(self.phi)).on(q),
|
|
110
|
+
ops.global_phase_operation(1j ** (2 * phase_correction_half_turns)),
|
|
82
111
|
]
|
|
83
112
|
|
|
84
113
|
def _value_equality_values_(self):
|
|
@@ -19,6 +19,7 @@ import re
|
|
|
19
19
|
|
|
20
20
|
import numpy as np
|
|
21
21
|
import pytest
|
|
22
|
+
import sympy
|
|
22
23
|
|
|
23
24
|
import cirq
|
|
24
25
|
from cirq.circuits.qasm_output import QasmTwoQubitGate, QasmUGate
|
|
@@ -29,6 +30,17 @@ def _make_qubits(n):
|
|
|
29
30
|
return [cirq.NamedQubit(f'q{i}') for i in range(n)]
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
def _qiskit_ugate_unitary(gate: QasmUGate) -> np.ndarray:
|
|
34
|
+
# Ref: https://quantum.cloud.ibm.com/docs/en/api/qiskit/qiskit.circuit.library.U3Gate#u3gate
|
|
35
|
+
th, ph, lm = np.pi * np.array([gate.theta, gate.phi, gate.lmda])
|
|
36
|
+
return np.array(
|
|
37
|
+
[
|
|
38
|
+
[np.cos(th / 2), -np.exp(1j * lm) * np.sin(th / 2)],
|
|
39
|
+
[np.exp(1j * ph) * np.sin(th / 2), np.exp(1j * (ph + lm)) * np.cos(th / 2)],
|
|
40
|
+
]
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
32
44
|
def test_u_gate_repr() -> None:
|
|
33
45
|
gate = QasmUGate(0.1, 0.2, 0.3)
|
|
34
46
|
assert repr(gate) == 'cirq.circuits.qasm_output.QasmUGate(theta=0.1, phi=0.2, lmda=0.3)'
|
|
@@ -43,6 +55,42 @@ def test_u_gate_eq() -> None:
|
|
|
43
55
|
cirq.approx_eq(gate4, gate3, atol=1e-16)
|
|
44
56
|
|
|
45
57
|
|
|
58
|
+
@pytest.mark.parametrize("_", range(10))
|
|
59
|
+
def test_u_gate_from_qiskit_ugate_unitary(_) -> None:
|
|
60
|
+
# QasmUGate at (theta, phi, lmda) is the same as QasmUGate at
|
|
61
|
+
# (2 - theta, phi + 1, lmda + 1) and a global phase factor of -1.
|
|
62
|
+
# QasmUGate.from_matrix resolves theta at [0, 1] and ignores possible global
|
|
63
|
+
# phase. To avoid phase discrepancy we limit theta to the [0, 1] interval.
|
|
64
|
+
theta = np.random.uniform(0, 1)
|
|
65
|
+
phi = np.random.uniform(0, 2)
|
|
66
|
+
lmda = np.random.uniform(0, 2)
|
|
67
|
+
u = _qiskit_ugate_unitary(QasmUGate(theta, phi, lmda))
|
|
68
|
+
g = QasmUGate.from_matrix(u)
|
|
69
|
+
np.testing.assert_allclose(cirq.unitary(g), u, atol=1e-7)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_u_gate_params() -> None:
|
|
73
|
+
q = cirq.LineQubit(0)
|
|
74
|
+
a, b, c = sympy.symbols('a b c')
|
|
75
|
+
u_gate = QasmUGate(a, b, c)
|
|
76
|
+
assert u_gate == QasmUGate(a, b + 2, c - 2)
|
|
77
|
+
assert u_gate != QasmUGate(a, b + 1, c - 1)
|
|
78
|
+
assert cirq.is_parameterized(u_gate)
|
|
79
|
+
assert cirq.parameter_names(u_gate) == {'a', 'b', 'c'}
|
|
80
|
+
assert not cirq.has_unitary(u_gate)
|
|
81
|
+
cirq.testing.assert_equivalent_repr(u_gate)
|
|
82
|
+
cirq.testing.assert_implements_consistent_protocols(u_gate)
|
|
83
|
+
u_gate_caps = cirq.resolve_parameters(u_gate, {'a': 'A', 'b': 'B', 'c': 'C'})
|
|
84
|
+
assert u_gate_caps == QasmUGate(*sympy.symbols('A B C'))
|
|
85
|
+
resolver = {'A': 0.1, 'B': 2.2, 'C': -1.7}
|
|
86
|
+
resolved = cirq.resolve_parameters(u_gate_caps, resolver)
|
|
87
|
+
assert cirq.approx_eq(resolved, QasmUGate(0.1, 0.2, 0.3))
|
|
88
|
+
resolved_then_decomposed = cirq.decompose_once_with_qubits(resolved, [q])
|
|
89
|
+
decomposed = cirq.decompose_once_with_qubits(u_gate_caps, [q])
|
|
90
|
+
decomposed_then_resolved = [cirq.resolve_parameters(g, resolver) for g in decomposed]
|
|
91
|
+
assert resolved_then_decomposed == decomposed_then_resolved
|
|
92
|
+
|
|
93
|
+
|
|
46
94
|
def test_qasm_two_qubit_gate_repr() -> None:
|
|
47
95
|
cirq.testing.assert_equivalent_repr(
|
|
48
96
|
QasmTwoQubitGate.from_matrix(cirq.testing.random_unitary(4))
|
|
@@ -53,13 +101,14 @@ def test_qasm_u_qubit_gate_unitary() -> None:
|
|
|
53
101
|
u = cirq.testing.random_unitary(2)
|
|
54
102
|
g = QasmUGate.from_matrix(u)
|
|
55
103
|
cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(g), u, atol=1e-7)
|
|
56
|
-
|
|
57
104
|
cirq.testing.assert_implements_consistent_protocols(g)
|
|
105
|
+
np.testing.assert_allclose(cirq.unitary(g), _qiskit_ugate_unitary(g), atol=1e-7)
|
|
58
106
|
|
|
59
107
|
u = cirq.unitary(cirq.Y)
|
|
60
108
|
g = QasmUGate.from_matrix(u)
|
|
61
109
|
cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(g), u, atol=1e-7)
|
|
62
110
|
cirq.testing.assert_implements_consistent_protocols(g)
|
|
111
|
+
np.testing.assert_allclose(cirq.unitary(g), _qiskit_ugate_unitary(g), atol=1e-7)
|
|
63
112
|
|
|
64
113
|
|
|
65
114
|
def test_qasm_two_qubit_gate_unitary() -> None:
|
|
@@ -200,7 +249,7 @@ ry(pi*-0.25) q[0];
|
|
|
200
249
|
)
|
|
201
250
|
|
|
202
251
|
|
|
203
|
-
def
|
|
252
|
+
def test_qasm_global_phase() -> None:
|
|
204
253
|
output = cirq.QasmOutput((cirq.global_phase_operation(np.exp(1j * 5))), ())
|
|
205
254
|
assert (
|
|
206
255
|
str(output)
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from collections.abc import Callable, Iterable, Mapping, Sequence
|
|
18
|
+
from typing import Any, cast, NamedTuple, Self, TYPE_CHECKING
|
|
18
19
|
|
|
19
20
|
import numpy as np
|
|
20
21
|
|