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/transformers/align_test.py
CHANGED
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import cirq
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def test_align_basic_no_context():
|
|
20
|
+
def test_align_basic_no_context() -> None:
|
|
21
21
|
q1 = cirq.NamedQubit('q1')
|
|
22
22
|
q2 = cirq.NamedQubit('q2')
|
|
23
23
|
c = cirq.Circuit(
|
|
@@ -45,7 +45,7 @@ def test_align_basic_no_context():
|
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def test_align_left_no_compile_context():
|
|
48
|
+
def test_align_left_no_compile_context() -> None:
|
|
49
49
|
q1 = cirq.NamedQubit('q1')
|
|
50
50
|
q2 = cirq.NamedQubit('q2')
|
|
51
51
|
cirq.testing.assert_same_circuits(
|
|
@@ -59,7 +59,7 @@ def test_align_left_no_compile_context():
|
|
|
59
59
|
cirq.measure(*[q1, q2], key='a'),
|
|
60
60
|
]
|
|
61
61
|
),
|
|
62
|
-
context=cirq.TransformerContext(tags_to_ignore=
|
|
62
|
+
context=cirq.TransformerContext(tags_to_ignore=("nocompile",)),
|
|
63
63
|
),
|
|
64
64
|
cirq.Circuit(
|
|
65
65
|
[
|
|
@@ -73,7 +73,7 @@ def test_align_left_no_compile_context():
|
|
|
73
73
|
)
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
def test_align_left_deep():
|
|
76
|
+
def test_align_left_deep() -> None:
|
|
77
77
|
q1, q2 = cirq.LineQubit.range(2)
|
|
78
78
|
c_nested = cirq.FrozenCircuit(
|
|
79
79
|
[
|
|
@@ -104,11 +104,11 @@ def test_align_left_deep():
|
|
|
104
104
|
c_nested_aligned,
|
|
105
105
|
cirq.CircuitOperation(c_nested_aligned).repeat(5).with_tags("preserve_tag"),
|
|
106
106
|
)
|
|
107
|
-
context = cirq.TransformerContext(tags_to_ignore=
|
|
107
|
+
context = cirq.TransformerContext(tags_to_ignore=("nocompile",), deep=True)
|
|
108
108
|
cirq.testing.assert_same_circuits(cirq.align_left(c_orig, context=context), c_expected)
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
def test_align_left_subset_of_operations():
|
|
111
|
+
def test_align_left_subset_of_operations() -> None:
|
|
112
112
|
q1 = cirq.NamedQubit('q1')
|
|
113
113
|
q2 = cirq.NamedQubit('q2')
|
|
114
114
|
tag = "op_to_align"
|
|
@@ -134,7 +134,7 @@ def test_align_left_subset_of_operations():
|
|
|
134
134
|
cirq.toggle_tags(
|
|
135
135
|
cirq.align_left(
|
|
136
136
|
cirq.toggle_tags(c_orig, [tag]),
|
|
137
|
-
context=cirq.TransformerContext(tags_to_ignore=
|
|
137
|
+
context=cirq.TransformerContext(tags_to_ignore=(tag,)),
|
|
138
138
|
),
|
|
139
139
|
[tag],
|
|
140
140
|
),
|
|
@@ -142,7 +142,7 @@ def test_align_left_subset_of_operations():
|
|
|
142
142
|
)
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
def test_align_right_no_compile_context():
|
|
145
|
+
def test_align_right_no_compile_context() -> None:
|
|
146
146
|
q1 = cirq.NamedQubit('q1')
|
|
147
147
|
q2 = cirq.NamedQubit('q2')
|
|
148
148
|
cirq.testing.assert_same_circuits(
|
|
@@ -156,7 +156,7 @@ def test_align_right_no_compile_context():
|
|
|
156
156
|
cirq.measure(*[q1, q2], key='a'),
|
|
157
157
|
]
|
|
158
158
|
),
|
|
159
|
-
context=cirq.TransformerContext(tags_to_ignore=
|
|
159
|
+
context=cirq.TransformerContext(tags_to_ignore=("nocompile",)),
|
|
160
160
|
),
|
|
161
161
|
cirq.Circuit(
|
|
162
162
|
[
|
|
@@ -170,7 +170,7 @@ def test_align_right_no_compile_context():
|
|
|
170
170
|
)
|
|
171
171
|
|
|
172
172
|
|
|
173
|
-
def test_align_right_deep():
|
|
173
|
+
def test_align_right_deep() -> None:
|
|
174
174
|
q1, q2 = cirq.LineQubit.range(2)
|
|
175
175
|
c_nested = cirq.FrozenCircuit(
|
|
176
176
|
cirq.Moment([cirq.X(q1)]),
|
|
@@ -199,11 +199,11 @@ def test_align_right_deep():
|
|
|
199
199
|
c_nested_aligned,
|
|
200
200
|
cirq.CircuitOperation(c_nested_aligned).repeat(5).with_tags("preserve_tag"),
|
|
201
201
|
)
|
|
202
|
-
context = cirq.TransformerContext(tags_to_ignore=
|
|
202
|
+
context = cirq.TransformerContext(tags_to_ignore=("nocompile",), deep=True)
|
|
203
203
|
cirq.testing.assert_same_circuits(cirq.align_right(c_orig, context=context), c_expected)
|
|
204
204
|
|
|
205
205
|
|
|
206
|
-
def test_classical_control():
|
|
206
|
+
def test_classical_control() -> None:
|
|
207
207
|
q0, q1 = cirq.LineQubit.range(2)
|
|
208
208
|
circuit = cirq.Circuit(
|
|
209
209
|
cirq.H(q0), cirq.measure(q0, key='m'), cirq.X(q1).with_classical_controls('m')
|
|
@@ -212,7 +212,7 @@ def test_classical_control():
|
|
|
212
212
|
cirq.testing.assert_same_circuits(cirq.align_right(circuit), circuit)
|
|
213
213
|
|
|
214
214
|
|
|
215
|
-
def test_measurement_and_classical_control_same_moment_preserve_order():
|
|
215
|
+
def test_measurement_and_classical_control_same_moment_preserve_order() -> None:
|
|
216
216
|
q0, q1 = cirq.LineQubit.range(2)
|
|
217
217
|
circuit = cirq.Circuit()
|
|
218
218
|
op_measure = cirq.measure(q0, key='m')
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import functools
|
|
20
|
+
from collections.abc import Sequence
|
|
20
21
|
from typing import TYPE_CHECKING
|
|
21
22
|
|
|
22
23
|
import numpy as np
|
|
@@ -31,7 +32,7 @@ def _X(
|
|
|
31
32
|
q: int,
|
|
32
33
|
args: sim.CliffordTableauSimulationState,
|
|
33
34
|
operations: list[ops.Operation],
|
|
34
|
-
qubits:
|
|
35
|
+
qubits: Sequence[cirq.Qid],
|
|
35
36
|
):
|
|
36
37
|
protocols.act_on(ops.X, args, qubits=[qubits[q]], allow_decompose=False)
|
|
37
38
|
operations.append(ops.X(qubits[q]))
|
|
@@ -41,7 +42,7 @@ def _Z(
|
|
|
41
42
|
q: int,
|
|
42
43
|
args: sim.CliffordTableauSimulationState,
|
|
43
44
|
operations: list[ops.Operation],
|
|
44
|
-
qubits:
|
|
45
|
+
qubits: Sequence[cirq.Qid],
|
|
45
46
|
):
|
|
46
47
|
protocols.act_on(ops.Z, args, qubits=[qubits[q]], allow_decompose=False)
|
|
47
48
|
operations.append(ops.Z(qubits[q]))
|
|
@@ -51,7 +52,7 @@ def _Sdg(
|
|
|
51
52
|
q: int,
|
|
52
53
|
args: sim.CliffordTableauSimulationState,
|
|
53
54
|
operations: list[ops.Operation],
|
|
54
|
-
qubits:
|
|
55
|
+
qubits: Sequence[cirq.Qid],
|
|
55
56
|
):
|
|
56
57
|
# Apply the tableau with S^\{dagger}
|
|
57
58
|
protocols.act_on(ops.S**-1, args, qubits=[qubits[q]], allow_decompose=False)
|
|
@@ -62,7 +63,7 @@ def _H(
|
|
|
62
63
|
q: int,
|
|
63
64
|
args: sim.CliffordTableauSimulationState,
|
|
64
65
|
operations: list[ops.Operation],
|
|
65
|
-
qubits:
|
|
66
|
+
qubits: Sequence[cirq.Qid],
|
|
66
67
|
):
|
|
67
68
|
protocols.act_on(ops.H, args, qubits=[qubits[q]], allow_decompose=False)
|
|
68
69
|
operations.append(ops.H(qubits[q]))
|
|
@@ -73,7 +74,7 @@ def _CNOT(
|
|
|
73
74
|
q2: int,
|
|
74
75
|
args: sim.CliffordTableauSimulationState,
|
|
75
76
|
operations: list[ops.Operation],
|
|
76
|
-
qubits:
|
|
77
|
+
qubits: Sequence[cirq.Qid],
|
|
77
78
|
):
|
|
78
79
|
protocols.act_on(ops.CNOT, args, qubits=[qubits[q1], qubits[q2]], allow_decompose=False)
|
|
79
80
|
operations.append(ops.CNOT(qubits[q1], qubits[q2]))
|
|
@@ -84,14 +85,14 @@ def _SWAP(
|
|
|
84
85
|
q2: int,
|
|
85
86
|
args: sim.CliffordTableauSimulationState,
|
|
86
87
|
operations: list[ops.Operation],
|
|
87
|
-
qubits:
|
|
88
|
+
qubits: Sequence[cirq.Qid],
|
|
88
89
|
):
|
|
89
90
|
protocols.act_on(ops.SWAP, args, qubits=[qubits[q1], qubits[q2]], allow_decompose=False)
|
|
90
91
|
operations.append(ops.SWAP(qubits[q1], qubits[q2]))
|
|
91
92
|
|
|
92
93
|
|
|
93
94
|
def decompose_clifford_tableau_to_operations(
|
|
94
|
-
qubits:
|
|
95
|
+
qubits: Sequence[cirq.Qid], clifford_tableau: qis.CliffordTableau
|
|
95
96
|
) -> list[ops.Operation]:
|
|
96
97
|
"""Decompose an n-qubit Clifford Tableau into a list of one/two qubit operations.
|
|
97
98
|
|
|
@@ -21,14 +21,14 @@ import cirq
|
|
|
21
21
|
from cirq.testing import assert_allclose_up_to_global_phase
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def test_misaligned_qubits():
|
|
24
|
+
def test_misaligned_qubits() -> None:
|
|
25
25
|
qubits = cirq.LineQubit.range(1)
|
|
26
26
|
tableau = cirq.CliffordTableau(num_qubits=2)
|
|
27
27
|
with pytest.raises(ValueError):
|
|
28
28
|
cirq.decompose_clifford_tableau_to_operations(qubits, tableau)
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def test_clifford_decompose_one_qubit():
|
|
31
|
+
def test_clifford_decompose_one_qubit() -> None:
|
|
32
32
|
"""Two random instance for one qubit decomposition."""
|
|
33
33
|
qubits = cirq.LineQubit.range(1)
|
|
34
34
|
args = cirq.CliffordTableauSimulationState(
|
|
@@ -63,7 +63,7 @@ def test_clifford_decompose_one_qubit():
|
|
|
63
63
|
assert_allclose_up_to_global_phase(cirq.unitary(expect_circ), cirq.unitary(circ), atol=1e-7)
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def test_clifford_decompose_two_qubits():
|
|
66
|
+
def test_clifford_decompose_two_qubits() -> None:
|
|
67
67
|
"""Two random instance for two qubits decomposition."""
|
|
68
68
|
qubits = cirq.LineQubit.range(2)
|
|
69
69
|
args = cirq.CliffordTableauSimulationState(
|
|
@@ -98,7 +98,7 @@ def test_clifford_decompose_two_qubits():
|
|
|
98
98
|
assert_allclose_up_to_global_phase(cirq.unitary(expect_circ), cirq.unitary(circ), atol=1e-7)
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
def test_clifford_decompose_by_unitary():
|
|
101
|
+
def test_clifford_decompose_by_unitary() -> None:
|
|
102
102
|
"""Validate the decomposition of random Clifford Tableau by unitary matrix.
|
|
103
103
|
|
|
104
104
|
Due to the exponential growth in dimension, it cannot validate very large number of qubits.
|
|
@@ -125,7 +125,7 @@ def test_clifford_decompose_by_unitary():
|
|
|
125
125
|
assert_allclose_up_to_global_phase(cirq.unitary(expect_circ), cirq.unitary(circ), atol=1e-7)
|
|
126
126
|
|
|
127
127
|
|
|
128
|
-
def test_clifford_decompose_by_reconstruction():
|
|
128
|
+
def test_clifford_decompose_by_reconstruction() -> None:
|
|
129
129
|
"""Validate the decomposition of random Clifford Tableau by reconstruction.
|
|
130
130
|
|
|
131
131
|
This approach can validate large number of qubits compared with the unitary one.
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import itertools
|
|
18
|
+
from collections.abc import Sequence
|
|
18
19
|
from typing import TYPE_CHECKING
|
|
19
20
|
|
|
20
21
|
import numpy as np
|
|
@@ -114,7 +115,7 @@ def _ccnot_congruent(c0: cirq.Qid, c1: cirq.Qid, target: cirq.Qid) -> list[cirq.
|
|
|
114
115
|
|
|
115
116
|
|
|
116
117
|
def decompose_multi_controlled_x(
|
|
117
|
-
controls:
|
|
118
|
+
controls: Sequence[cirq.Qid], target: cirq.Qid, free_qubits: Sequence[cirq.Qid]
|
|
118
119
|
) -> list[cirq.Operation]:
|
|
119
120
|
"""Implements action of multi-controlled Pauli X gate.
|
|
120
121
|
|
|
@@ -152,11 +153,11 @@ def decompose_multi_controlled_x(
|
|
|
152
153
|
elif len(free_qubits) >= 1:
|
|
153
154
|
# See [1], Lemma 7.3.
|
|
154
155
|
m1 = n // 2
|
|
155
|
-
free1 = controls[m1:]
|
|
156
|
+
free1 = [*controls[m1:], target, *free_qubits[1:]]
|
|
156
157
|
ctrl1 = controls[:m1]
|
|
157
158
|
part1 = decompose_multi_controlled_x(ctrl1, free_qubits[0], free1)
|
|
158
|
-
free2 = controls[:m1]
|
|
159
|
-
ctrl2 = controls[m1:]
|
|
159
|
+
free2 = [*controls[:m1], *free_qubits[1:]]
|
|
160
|
+
ctrl2 = [*controls[m1:], free_qubits[0]]
|
|
160
161
|
part2 = decompose_multi_controlled_x(ctrl2, target, free2)
|
|
161
162
|
return [*part1, *part2, *part1, *part2]
|
|
162
163
|
else:
|
|
@@ -167,7 +168,7 @@ def decompose_multi_controlled_x(
|
|
|
167
168
|
|
|
168
169
|
|
|
169
170
|
def _decompose_su(
|
|
170
|
-
matrix: np.ndarray, controls:
|
|
171
|
+
matrix: np.ndarray, controls: Sequence[cirq.Qid], target: cirq.Qid
|
|
171
172
|
) -> list[cirq.Operation]:
|
|
172
173
|
"""Decomposes controlled special unitary gate into elementary gates.
|
|
173
174
|
|
|
@@ -193,9 +194,9 @@ def _decompose_su(
|
|
|
193
194
|
def _decompose_recursive(
|
|
194
195
|
matrix: np.ndarray,
|
|
195
196
|
power: float,
|
|
196
|
-
controls:
|
|
197
|
+
controls: Sequence[cirq.Qid],
|
|
197
198
|
target: cirq.Qid,
|
|
198
|
-
free_qubits:
|
|
199
|
+
free_qubits: Sequence[cirq.Qid],
|
|
199
200
|
) -> list[cirq.Operation]:
|
|
200
201
|
"""Decomposes controlled unitary gate into elementary gates.
|
|
201
202
|
|
|
@@ -205,20 +206,20 @@ def _decompose_recursive(
|
|
|
205
206
|
if len(controls) == 1:
|
|
206
207
|
return _decompose_single_ctrl(_unitary_power(matrix, power), controls[0], target)
|
|
207
208
|
|
|
208
|
-
cnots = decompose_multi_controlled_x(controls[:-1], controls[-1], free_qubits
|
|
209
|
+
cnots = decompose_multi_controlled_x(controls[:-1], controls[-1], [*free_qubits, target])
|
|
209
210
|
return [
|
|
210
211
|
*_decompose_single_ctrl(_unitary_power(matrix, 0.5 * power), controls[-1], target),
|
|
211
212
|
*cnots,
|
|
212
213
|
*_decompose_single_ctrl(_unitary_power(matrix, -0.5 * power), controls[-1], target),
|
|
213
214
|
*cnots,
|
|
214
215
|
*_decompose_recursive(
|
|
215
|
-
matrix, 0.5 * power, controls[:-1], target, [controls[-1]
|
|
216
|
+
matrix, 0.5 * power, controls[:-1], target, [controls[-1], *free_qubits]
|
|
216
217
|
),
|
|
217
218
|
]
|
|
218
219
|
|
|
219
220
|
|
|
220
221
|
def decompose_multi_controlled_rotation(
|
|
221
|
-
matrix: np.ndarray, controls:
|
|
222
|
+
matrix: np.ndarray, controls: Sequence[cirq.Qid], target: cirq.Qid
|
|
222
223
|
) -> list[cirq.Operation]:
|
|
223
224
|
"""Implements action of multi-controlled unitary gate.
|
|
224
225
|
|
|
@@ -20,7 +20,7 @@ import scipy.stats
|
|
|
20
20
|
import cirq
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def test_decompose_x():
|
|
23
|
+
def test_decompose_x() -> None:
|
|
24
24
|
"""Verifies correctness of multi-controlled X decomposition."""
|
|
25
25
|
for total_qubits_count in range(1, 8):
|
|
26
26
|
qubits = cirq.LineQubit.range(total_qubits_count)
|
|
@@ -83,14 +83,14 @@ def _test_decompose(matrix, controls_count):
|
|
|
83
83
|
cirq.testing.assert_allclose_up_to_global_phase(expected_matrix, result_matrix, atol=1e-8)
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
def test_decompose_specific_matrices():
|
|
86
|
+
def test_decompose_specific_matrices() -> None:
|
|
87
87
|
for gate in [cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.I, cirq.T, cirq.S]:
|
|
88
88
|
for controls_count in range(7):
|
|
89
89
|
_test_decompose(cirq.unitary(gate), controls_count)
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
@cirq.testing.retry_once_with_later_random_values
|
|
93
|
-
def test_decompose_random_unitary():
|
|
93
|
+
def test_decompose_random_unitary() -> None:
|
|
94
94
|
for controls_count in range(5):
|
|
95
95
|
for _ in range(10):
|
|
96
96
|
_test_decompose(_random_unitary(), controls_count)
|
|
@@ -99,7 +99,7 @@ def test_decompose_random_unitary():
|
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
@cirq.testing.retry_once_with_later_random_values
|
|
102
|
-
def test_decompose_random_special_unitary():
|
|
102
|
+
def test_decompose_random_special_unitary() -> None:
|
|
103
103
|
for controls_count in range(5):
|
|
104
104
|
for _ in range(10):
|
|
105
105
|
_test_decompose(_random_special_unitary(), controls_count)
|
|
@@ -113,7 +113,7 @@ def _decomposition_size(U, controls_count):
|
|
|
113
113
|
return _count_operations(operations)
|
|
114
114
|
|
|
115
115
|
|
|
116
|
-
def test_decompose_size_special_unitary():
|
|
116
|
+
def test_decompose_size_special_unitary() -> None:
|
|
117
117
|
np.random.seed(0)
|
|
118
118
|
u = _random_special_unitary()
|
|
119
119
|
assert _decomposition_size(u, 0) == (1, 0, 0)
|
|
@@ -126,7 +126,7 @@ def test_decompose_size_special_unitary():
|
|
|
126
126
|
assert _decomposition_size(u, i) == (64 * i - 312, 48 * i - 234, 16)
|
|
127
127
|
|
|
128
128
|
|
|
129
|
-
def test_decompose_size_unitary():
|
|
129
|
+
def test_decompose_size_unitary() -> None:
|
|
130
130
|
np.random.seed(0)
|
|
131
131
|
u = _random_unitary()
|
|
132
132
|
assert _decomposition_size(u, 0) == (1, 0, 0)
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from collections.abc import Sequence
|
|
18
|
+
from typing import TYPE_CHECKING
|
|
18
19
|
|
|
19
20
|
import numpy as np
|
|
20
21
|
import sympy
|
|
@@ -100,7 +101,7 @@ def decompose_cphase_into_two_fsim(
|
|
|
100
101
|
fsim_gate: cirq.FSimGate,
|
|
101
102
|
qubits: Sequence[cirq.Qid] | None = None,
|
|
102
103
|
atol: float = 1e-8,
|
|
103
|
-
) -> cirq.
|
|
104
|
+
) -> Sequence[cirq.Operation]:
|
|
104
105
|
"""Decomposes CZPowGate into two FSimGates.
|
|
105
106
|
|
|
106
107
|
This function implements the decomposition described in section VII F I
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import itertools
|
|
18
|
-
from
|
|
18
|
+
from collections.abc import Sequence
|
|
19
19
|
|
|
20
20
|
import numpy as np
|
|
21
21
|
import pytest
|
|
@@ -24,7 +24,7 @@ import sympy
|
|
|
24
24
|
import cirq
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def test_symbols():
|
|
27
|
+
def test_symbols() -> None:
|
|
28
28
|
with pytest.raises(ValueError, match='Symbolic arguments'):
|
|
29
29
|
cirq.compute_cphase_exponents_for_fsim_decomposition(
|
|
30
30
|
cirq.FSimGate(theta=sympy.Symbol('t'), phi=sympy.Symbol('phi'))
|
|
@@ -36,8 +36,9 @@ class FakeSycamoreGate(cirq.FSimGate):
|
|
|
36
36
|
super().__init__(theta=np.pi / 2, phi=np.pi / 6)
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
def test_parameterized_gates():
|
|
39
|
+
def test_parameterized_gates() -> None:
|
|
40
40
|
t = sympy.Symbol('t')
|
|
41
|
+
fsim_gate: cirq.FSimGate
|
|
41
42
|
with pytest.raises(ValueError):
|
|
42
43
|
cphase_gate = cirq.CZPowGate(exponent=t)
|
|
43
44
|
fsim_gate = FakeSycamoreGate()
|
|
@@ -54,14 +55,14 @@ def test_parameterized_gates():
|
|
|
54
55
|
cirq.decompose_cphase_into_two_fsim(cphase_gate, fsim_gate=fsim_gate)
|
|
55
56
|
|
|
56
57
|
|
|
57
|
-
def test_invalid_qubits():
|
|
58
|
+
def test_invalid_qubits() -> None:
|
|
58
59
|
with pytest.raises(ValueError):
|
|
59
60
|
cirq.decompose_cphase_into_two_fsim(
|
|
60
61
|
cphase_gate=cirq.CZ, fsim_gate=FakeSycamoreGate(), qubits=cirq.LineQubit.range(3)
|
|
61
62
|
)
|
|
62
63
|
|
|
63
64
|
|
|
64
|
-
def test_circuit_structure():
|
|
65
|
+
def test_circuit_structure() -> None:
|
|
65
66
|
syc = FakeSycamoreGate()
|
|
66
67
|
ops = cirq.decompose_cphase_into_two_fsim(cirq.CZ, fsim_gate=syc)
|
|
67
68
|
num_interaction_moments = 0
|
|
@@ -73,7 +74,7 @@ def test_circuit_structure():
|
|
|
73
74
|
assert num_interaction_moments == 2
|
|
74
75
|
|
|
75
76
|
|
|
76
|
-
def assert_decomposition_valid(cphase_gate, fsim_gate):
|
|
77
|
+
def assert_decomposition_valid(cphase_gate, fsim_gate) -> None:
|
|
77
78
|
u_expected = cirq.unitary(cphase_gate)
|
|
78
79
|
ops = cirq.decompose_cphase_into_two_fsim(cphase_gate, fsim_gate=fsim_gate)
|
|
79
80
|
u_actual = cirq.unitary(cirq.Circuit(ops))
|
|
@@ -83,7 +84,7 @@ def assert_decomposition_valid(cphase_gate, fsim_gate):
|
|
|
83
84
|
@pytest.mark.parametrize(
|
|
84
85
|
'exponent', (-5.5, -3, -1.5, -1, -0.65, -0.2, 0, 0.1, 0.75, 1, 1.5, 2, 5.5)
|
|
85
86
|
)
|
|
86
|
-
def test_decomposition_to_sycamore_gate(exponent):
|
|
87
|
+
def test_decomposition_to_sycamore_gate(exponent) -> None:
|
|
87
88
|
cphase_gate = cirq.CZPowGate(exponent=exponent)
|
|
88
89
|
assert_decomposition_valid(cphase_gate, FakeSycamoreGate())
|
|
89
90
|
|
|
@@ -95,7 +96,7 @@ def test_decomposition_to_sycamore_gate(exponent):
|
|
|
95
96
|
(-1.4 * np.pi, -np.pi / 9, np.pi / 11, np.pi / 2, 2.4 * np.pi),
|
|
96
97
|
),
|
|
97
98
|
)
|
|
98
|
-
def test_valid_cphase_exponents(theta, phi):
|
|
99
|
+
def test_valid_cphase_exponents(theta, phi) -> None:
|
|
99
100
|
fsim_gate = cirq.FSimGate(theta=theta, phi=phi)
|
|
100
101
|
valid_exponent_intervals = cirq.compute_cphase_exponents_for_fsim_decomposition(fsim_gate)
|
|
101
102
|
assert valid_exponent_intervals
|
|
@@ -131,7 +132,7 @@ def complement_intervals(intervals: Sequence[tuple[float, float]]) -> Sequence[t
|
|
|
131
132
|
(-1.7 * np.pi, -np.pi / 5, np.pi / 7, 2.5 * np.pi),
|
|
132
133
|
),
|
|
133
134
|
)
|
|
134
|
-
def test_invalid_cphase_exponents(theta, phi):
|
|
135
|
+
def test_invalid_cphase_exponents(theta, phi) -> None:
|
|
135
136
|
fsim_gate = cirq.FSimGate(theta=theta, phi=phi)
|
|
136
137
|
valid_exponent_intervals = cirq.compute_cphase_exponents_for_fsim_decomposition(fsim_gate)
|
|
137
138
|
invalid_exponent_intervals = complement_intervals(valid_exponent_intervals)
|
|
@@ -151,6 +152,6 @@ def test_invalid_cphase_exponents(theta, phi):
|
|
|
151
152
|
@pytest.mark.parametrize(
|
|
152
153
|
'bad_fsim_gate', (cirq.FSimGate(theta=0, phi=0), cirq.FSimGate(theta=np.pi / 4, phi=np.pi / 2))
|
|
153
154
|
)
|
|
154
|
-
def test_invalid_fsim_gate(bad_fsim_gate):
|
|
155
|
+
def test_invalid_fsim_gate(bad_fsim_gate) -> None:
|
|
155
156
|
with pytest.raises(ValueError):
|
|
156
157
|
cirq.decompose_cphase_into_two_fsim(cirq.CZ, fsim_gate=bad_fsim_gate)
|
|
@@ -21,10 +21,11 @@ https://arxiv.org/abs/quant-ph/0406176
|
|
|
21
21
|
|
|
22
22
|
from __future__ import annotations
|
|
23
23
|
|
|
24
|
-
from
|
|
24
|
+
from collections.abc import Callable, Iterable, Sequence
|
|
25
|
+
from typing import cast, TYPE_CHECKING
|
|
25
26
|
|
|
27
|
+
import attrs
|
|
26
28
|
import numpy as np
|
|
27
|
-
from attr import define
|
|
28
29
|
from scipy.linalg import cossin
|
|
29
30
|
|
|
30
31
|
from cirq import ops
|
|
@@ -40,14 +41,14 @@ if TYPE_CHECKING:
|
|
|
40
41
|
import cirq
|
|
41
42
|
|
|
42
43
|
|
|
43
|
-
@define
|
|
44
|
+
@attrs.define
|
|
44
45
|
class _TwoQubitGate:
|
|
45
46
|
location: int
|
|
46
47
|
matrix: np.ndarray
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
def quantum_shannon_decomposition(
|
|
50
|
-
qubits:
|
|
51
|
+
qubits: Sequence[cirq.Qid], u: np.ndarray, atol: float = 1e-8
|
|
51
52
|
) -> Iterable[cirq.Operation]:
|
|
52
53
|
"""Decomposes n-qubit unitary 1-q, 2-q and GlobalPhase gates, preserving global phase.
|
|
53
54
|
|
|
@@ -149,7 +150,7 @@ def quantum_shannon_decomposition(
|
|
|
149
150
|
yield from cast(Iterable[ops.Operation], ops.flatten_op_tree(shannon_decomp))
|
|
150
151
|
|
|
151
152
|
|
|
152
|
-
def _recursive_decomposition(qubits:
|
|
153
|
+
def _recursive_decomposition(qubits: Sequence[cirq.Qid], u: np.ndarray) -> Iterable[cirq.Operation]:
|
|
153
154
|
"""Recursive step in the quantum shannon decomposition.
|
|
154
155
|
|
|
155
156
|
Decomposes n-qubit unitary into generic 2-qubit gates, CNOT, CZ and 1-qubit gates.
|
|
@@ -270,7 +271,7 @@ def _single_qubit_decomposition(qubit: cirq.Qid, u: np.ndarray) -> Iterable[cirq
|
|
|
270
271
|
|
|
271
272
|
|
|
272
273
|
def _msb_demuxer(
|
|
273
|
-
demux_qubits:
|
|
274
|
+
demux_qubits: Sequence[cirq.Qid], u1: np.ndarray, u2: np.ndarray
|
|
274
275
|
) -> Iterable[cirq.Operation]:
|
|
275
276
|
"""Demultiplexes a unitary matrix that is multiplexed in its most-significant-qubit.
|
|
276
277
|
|
|
@@ -336,7 +337,7 @@ def _nth_gray(n: int) -> int:
|
|
|
336
337
|
|
|
337
338
|
|
|
338
339
|
def _multiplexed_cossin(
|
|
339
|
-
cossin_qubits:
|
|
340
|
+
cossin_qubits: Sequence[cirq.Qid], angles: list[float], rot_func: Callable = ops.ry
|
|
340
341
|
) -> Iterable[cirq.Operation]:
|
|
341
342
|
"""Performs a multiplexed rotation over all qubits in this unitary matrix,
|
|
342
343
|
|
|
@@ -31,9 +31,8 @@ from cirq.transformers.analytical_decompositions.quantum_shannon_decomposition i
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
@pytest.mark.xfail(reason='#6765')
|
|
35
34
|
@pytest.mark.parametrize('n_qubits', list(range(1, 8)))
|
|
36
|
-
def test_random_qsd_n_qubit(n_qubits):
|
|
35
|
+
def test_random_qsd_n_qubit(n_qubits) -> None:
|
|
37
36
|
U = unitary_group.rvs(2**n_qubits)
|
|
38
37
|
qubits = [cirq.NamedQubit(f'q{i}') for i in range(n_qubits)]
|
|
39
38
|
circuit = cirq.Circuit(quantum_shannon_decomposition(qubits, U))
|
|
@@ -43,7 +42,7 @@ def test_random_qsd_n_qubit(n_qubits):
|
|
|
43
42
|
assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
def test_qsd_n_qubit_errors():
|
|
45
|
+
def test_qsd_n_qubit_errors() -> None:
|
|
47
46
|
qubits = [cirq.NamedQubit(f'q{i}') for i in range(3)]
|
|
48
47
|
with pytest.raises(ValueError, match="shaped numpy array"):
|
|
49
48
|
cirq.Circuit(quantum_shannon_decomposition(qubits, np.eye(9)))
|
|
@@ -51,7 +50,7 @@ def test_qsd_n_qubit_errors():
|
|
|
51
50
|
cirq.Circuit(quantum_shannon_decomposition(qubits, np.ones((8, 8))))
|
|
52
51
|
|
|
53
52
|
|
|
54
|
-
def test_recursive_decomposition_n_qubit_errors():
|
|
53
|
+
def test_recursive_decomposition_n_qubit_errors() -> None:
|
|
55
54
|
qubits = [cirq.NamedQubit(f'q{i}') for i in range(3)]
|
|
56
55
|
with pytest.raises(ValueError, match="shaped numpy array"):
|
|
57
56
|
cirq.Circuit(_recursive_decomposition(qubits, np.eye(9)))
|
|
@@ -59,7 +58,7 @@ def test_recursive_decomposition_n_qubit_errors():
|
|
|
59
58
|
cirq.Circuit(_recursive_decomposition(qubits, np.eye(2)))
|
|
60
59
|
|
|
61
60
|
|
|
62
|
-
def test_random_single_qubit_decomposition():
|
|
61
|
+
def test_random_single_qubit_decomposition() -> None:
|
|
63
62
|
U = unitary_group.rvs(2)
|
|
64
63
|
qubit = cirq.NamedQubit('q0')
|
|
65
64
|
circuit = cirq.Circuit(_single_qubit_decomposition(qubit, U))
|
|
@@ -69,7 +68,7 @@ def test_random_single_qubit_decomposition():
|
|
|
69
68
|
assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
|
|
70
69
|
|
|
71
70
|
|
|
72
|
-
def test_msb_demuxer():
|
|
71
|
+
def test_msb_demuxer() -> None:
|
|
73
72
|
U1 = unitary_group.rvs(4)
|
|
74
73
|
U2 = unitary_group.rvs(4)
|
|
75
74
|
U_full = np.kron([[1, 0], [0, 0]], U1) + np.kron([[0, 0], [0, 1]], U2)
|
|
@@ -81,13 +80,12 @@ def test_msb_demuxer():
|
|
|
81
80
|
assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
|
|
82
81
|
|
|
83
82
|
|
|
84
|
-
def test_multiplexed_cossin():
|
|
83
|
+
def test_multiplexed_cossin() -> None:
|
|
85
84
|
angle_1 = np.random.random_sample() * 2 * np.pi
|
|
86
85
|
angle_2 = np.random.random_sample() * 2 * np.pi
|
|
87
86
|
c1, s1 = np.cos(angle_1), np.sin(angle_1)
|
|
88
87
|
c2, s2 = np.cos(angle_2), np.sin(angle_2)
|
|
89
|
-
multiplexed_ry = [[c1, 0, -s1, 0], [0, c2, 0, -s2], [s1, 0, c1, 0], [0, s2, 0, c2]]
|
|
90
|
-
multiplexed_ry = np.array(multiplexed_ry)
|
|
88
|
+
multiplexed_ry = np.asarray([[c1, 0, -s1, 0], [0, c2, 0, -s2], [s1, 0, c1, 0], [0, s2, 0, c2]])
|
|
91
89
|
qubits = [cirq.NamedQubit(f'q{i}') for i in range(2)]
|
|
92
90
|
circuit = cirq.Circuit(_multiplexed_cossin(qubits, [angle_1, angle_2]))
|
|
93
91
|
# Add back the CZ gate removed by the A.1 optimization
|
|
@@ -126,11 +124,11 @@ def test_multiplexed_cossin():
|
|
|
126
124
|
(15, 8),
|
|
127
125
|
],
|
|
128
126
|
)
|
|
129
|
-
def test_nth_gray(n, gray):
|
|
127
|
+
def test_nth_gray(n, gray) -> None:
|
|
130
128
|
assert _nth_gray(n) == gray
|
|
131
129
|
|
|
132
130
|
|
|
133
|
-
def test_ghz_circuit_decomposes():
|
|
131
|
+
def test_ghz_circuit_decomposes() -> None:
|
|
134
132
|
# Test case from #6725
|
|
135
133
|
ghz_circuit = cirq.Circuit(cirq.H(cirq.q(0)), cirq.CNOT(cirq.q(0), cirq.q(1)))
|
|
136
134
|
ghz_unitary = cirq.unitary(ghz_circuit)
|
|
@@ -141,7 +139,7 @@ def test_ghz_circuit_decomposes():
|
|
|
141
139
|
np.testing.assert_allclose(new_unitary, ghz_unitary, atol=1e-6)
|
|
142
140
|
|
|
143
141
|
|
|
144
|
-
def test_qft_decomposes():
|
|
142
|
+
def test_qft_decomposes() -> None:
|
|
145
143
|
# Test case from #6666
|
|
146
144
|
qs = cirq.LineQubit.range(4)
|
|
147
145
|
qft_circuit = cirq.Circuit(cirq.qft(*qs))
|
|
@@ -163,7 +161,7 @@ def test_qft_decomposes():
|
|
|
163
161
|
(cirq.S, 1), # rz & ry
|
|
164
162
|
],
|
|
165
163
|
)
|
|
166
|
-
def test_cliffords(gate, num_ops):
|
|
164
|
+
def test_cliffords(gate, num_ops) -> None:
|
|
167
165
|
desired_unitary = cirq.unitary(gate)
|
|
168
166
|
shannon_circuit = cirq.Circuit(quantum_shannon_decomposition((cirq.q(0),), desired_unitary))
|
|
169
167
|
new_unitary = cirq.unitary(shannon_circuit)
|
|
@@ -173,7 +171,7 @@ def test_cliffords(gate, num_ops):
|
|
|
173
171
|
|
|
174
172
|
|
|
175
173
|
@pytest.mark.parametrize('gate', [cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.S])
|
|
176
|
-
def test_cliffords_with_global_phase(gate):
|
|
174
|
+
def test_cliffords_with_global_phase(gate) -> None:
|
|
177
175
|
global_phase = np.exp(1j * np.random.choice(np.linspace(0.1, 2 * np.pi, 10)))
|
|
178
176
|
desired_unitary = cirq.unitary(gate) * global_phase
|
|
179
177
|
shannon_circuit = cirq.Circuit(quantum_shannon_decomposition((cirq.q(0),), desired_unitary))
|
|
@@ -181,7 +179,7 @@ def test_cliffords_with_global_phase(gate):
|
|
|
181
179
|
np.testing.assert_allclose(new_unitary, desired_unitary)
|
|
182
180
|
|
|
183
181
|
|
|
184
|
-
def test_global_phase():
|
|
182
|
+
def test_global_phase() -> None:
|
|
185
183
|
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
186
184
|
shannon_circuit = cirq.Circuit(
|
|
187
185
|
quantum_shannon_decomposition((cirq.q(0),), np.eye(2) * global_phase)
|
|
@@ -191,7 +189,7 @@ def test_global_phase():
|
|
|
191
189
|
|
|
192
190
|
|
|
193
191
|
@pytest.mark.parametrize('gate', [cirq.CZ, cirq.CNOT, cirq.XX, cirq.YY, cirq.ZZ])
|
|
194
|
-
def test_two_qubit_gate(gate):
|
|
192
|
+
def test_two_qubit_gate(gate) -> None:
|
|
195
193
|
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
196
194
|
desired_unitary = cirq.unitary(gate) * global_phase
|
|
197
195
|
shannon_circuit = cirq.Circuit(
|
|
@@ -202,7 +200,7 @@ def test_two_qubit_gate(gate):
|
|
|
202
200
|
|
|
203
201
|
|
|
204
202
|
@pytest.mark.parametrize('gate', [cirq.CCNOT, cirq.qft(*cirq.LineQubit.range(3))])
|
|
205
|
-
def test_three_qubit_gate(gate):
|
|
203
|
+
def test_three_qubit_gate(gate) -> None:
|
|
206
204
|
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
207
205
|
desired_unitary = cirq.unitary(gate) * global_phase
|
|
208
206
|
shannon_circuit = cirq.Circuit(
|
|
@@ -212,8 +210,7 @@ def test_three_qubit_gate(gate):
|
|
|
212
210
|
np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
|
|
213
211
|
|
|
214
212
|
|
|
215
|
-
|
|
216
|
-
def test_qft5():
|
|
213
|
+
def test_qft5() -> None:
|
|
217
214
|
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
218
215
|
desired_unitary = cirq.unitary(cirq.qft(*cirq.LineQubit.range(5))) * global_phase
|
|
219
216
|
shannon_circuit = cirq.Circuit(
|
|
@@ -223,7 +220,7 @@ def test_qft5():
|
|
|
223
220
|
np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
|
|
224
221
|
|
|
225
222
|
|
|
226
|
-
def test_random_circuit_decomposition():
|
|
223
|
+
def test_random_circuit_decomposition() -> None:
|
|
227
224
|
qubits = cirq.LineQubit.range(3)
|
|
228
225
|
test_circuit = (
|
|
229
226
|
random_two_qubit_circuit_with_czs(3, qubits[0], qubits[1])
|