cirq-core 1.4.0.dev20240529225110__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/__init__.py +587 -569
- cirq/_compat.py +9 -0
- cirq/_compat_test.py +11 -9
- cirq/_import.py +7 -8
- cirq/_version.py +31 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/__init__.py +15 -9
- cirq/circuits/_block_diagram_drawer.py +1 -2
- cirq/circuits/_block_diagram_drawer_test.py +3 -3
- cirq/circuits/_box_drawing_character_data.py +0 -1
- cirq/circuits/_box_drawing_character_data_test.py +2 -2
- cirq/circuits/_bucket_priority_queue.py +0 -1
- cirq/circuits/_bucket_priority_queue_test.py +1 -1
- cirq/circuits/circuit.py +336 -234
- cirq/circuits/circuit_operation.py +102 -52
- cirq/circuits/circuit_operation_test.py +85 -4
- cirq/circuits/circuit_test.py +101 -32
- cirq/circuits/frozen_circuit.py +36 -32
- cirq/circuits/insert_strategy.py +10 -0
- cirq/circuits/insert_strategy_test.py +20 -0
- cirq/circuits/moment.py +79 -80
- cirq/circuits/moment_test.py +105 -2
- cirq/circuits/optimization_pass.py +15 -15
- cirq/circuits/optimization_pass_test.py +8 -9
- cirq/circuits/qasm_output.py +64 -33
- cirq/circuits/qasm_output_test.py +63 -2
- cirq/circuits/text_diagram_drawer.py +26 -56
- cirq/circuits/text_diagram_drawer_test.py +5 -4
- cirq/contrib/__init__.py +2 -2
- cirq/contrib/acquaintance/__init__.py +44 -29
- cirq/contrib/acquaintance/bipartite.py +8 -7
- cirq/contrib/acquaintance/bipartite_test.py +11 -1
- cirq/contrib/acquaintance/devices.py +5 -4
- cirq/contrib/acquaintance/devices_test.py +5 -1
- cirq/contrib/acquaintance/executor.py +18 -21
- cirq/contrib/acquaintance/executor_test.py +3 -2
- cirq/contrib/acquaintance/gates.py +36 -27
- cirq/contrib/acquaintance/gates_test.py +1 -1
- cirq/contrib/acquaintance/inspection_utils.py +10 -9
- cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
- cirq/contrib/acquaintance/mutation_utils.py +10 -10
- cirq/contrib/acquaintance/optimizers.py +7 -6
- cirq/contrib/acquaintance/optimizers_test.py +1 -1
- cirq/contrib/acquaintance/permutation.py +22 -21
- cirq/contrib/acquaintance/permutation_test.py +1 -1
- cirq/contrib/acquaintance/shift.py +8 -6
- cirq/contrib/acquaintance/shift_swap_network.py +6 -4
- cirq/contrib/acquaintance/strategies/__init__.py +9 -3
- cirq/contrib/acquaintance/strategies/complete.py +4 -3
- cirq/contrib/acquaintance/strategies/cubic.py +5 -3
- cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
- cirq/contrib/acquaintance/topological_sort.py +4 -2
- cirq/contrib/bayesian_network/__init__.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
- cirq/contrib/circuitdag/__init__.py +1 -1
- cirq/contrib/circuitdag/circuit_dag.py +24 -24
- cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
- cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
- cirq/contrib/graph_device/__init__.py +8 -8
- cirq/contrib/graph_device/graph_device.py +8 -8
- cirq/contrib/graph_device/graph_device_test.py +0 -1
- cirq/contrib/graph_device/hypergraph_test.py +1 -0
- cirq/contrib/json.py +1 -2
- cirq/contrib/json_test.py +2 -2
- cirq/contrib/noise_models/__init__.py +5 -6
- cirq/contrib/noise_models/noise_models.py +8 -6
- cirq/contrib/paulistring/__init__.py +22 -10
- cirq/contrib/paulistring/clifford_optimize.py +1 -1
- cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
- cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
- cirq/contrib/paulistring/optimize.py +2 -2
- cirq/contrib/paulistring/optimize_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
- cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
- cirq/contrib/paulistring/recombine.py +2 -2
- cirq/contrib/paulistring/recombine_test.py +2 -2
- cirq/contrib/paulistring/separate.py +3 -4
- cirq/contrib/qasm_import/__init__.py +2 -2
- cirq/contrib/qasm_import/_lexer.py +21 -26
- cirq/contrib/qasm_import/_lexer_test.py +90 -6
- cirq/contrib/qasm_import/_parser.py +238 -47
- cirq/contrib/qasm_import/_parser_test.py +514 -59
- cirq/contrib/qasm_import/qasm_test.py +1 -1
- cirq/contrib/qcircuit/__init__.py +6 -4
- cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
- cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
- cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
- cirq/contrib/qcircuit/qcircuit_test.py +1 -1
- cirq/contrib/quantum_volume/__init__.py +7 -7
- cirq/contrib/quantum_volume/quantum_volume.py +6 -11
- cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
- cirq/contrib/quimb/__init__.py +16 -13
- cirq/contrib/quimb/density_matrix.py +1 -1
- cirq/contrib/quimb/mps_simulator.py +27 -28
- cirq/contrib/quimb/mps_simulator_test.py +5 -0
- cirq/contrib/quimb/state_vector.py +3 -10
- cirq/contrib/quirk/__init__.py +1 -1
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/routing/__init__.py +12 -9
- cirq/contrib/routing/device.py +1 -1
- cirq/contrib/routing/device_test.py +1 -2
- cirq/contrib/routing/greedy.py +7 -5
- cirq/contrib/routing/greedy_test.py +5 -3
- cirq/contrib/routing/initialization.py +3 -1
- cirq/contrib/routing/initialization_test.py +1 -1
- cirq/contrib/routing/swap_network.py +6 -6
- cirq/contrib/routing/utils.py +6 -4
- cirq/contrib/routing/utils_test.py +1 -2
- cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
- cirq/contrib/svg/__init__.py +1 -1
- cirq/contrib/svg/svg.py +12 -10
- cirq/contrib/svg/svg_test.py +3 -2
- cirq/devices/__init__.py +34 -25
- cirq/devices/device.py +16 -12
- cirq/devices/device_test.py +1 -0
- cirq/devices/grid_device_metadata.py +16 -12
- cirq/devices/grid_device_metadata_test.py +2 -1
- cirq/devices/grid_qubit.py +31 -26
- cirq/devices/grid_qubit_test.py +30 -1
- cirq/devices/insertion_noise_model.py +6 -6
- cirq/devices/insertion_noise_model_test.py +1 -1
- cirq/devices/line_qubit.py +28 -20
- cirq/devices/line_qubit_test.py +26 -0
- cirq/devices/named_topologies.py +12 -10
- cirq/devices/named_topologies_test.py +5 -4
- cirq/devices/noise_model.py +29 -33
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +2 -2
- cirq/devices/noise_utils.py +3 -3
- cirq/devices/superconducting_qubits_noise_properties.py +2 -2
- cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
- cirq/devices/thermal_noise_model.py +2 -1
- cirq/devices/unconstrained_device.py +1 -1
- cirq/devices/unconstrained_device_test.py +6 -0
- cirq/experiments/__init__.py +51 -34
- cirq/experiments/qubit_characterizations.py +17 -15
- cirq/experiments/qubit_characterizations_test.py +4 -6
- cirq/experiments/random_quantum_circuit_generation.py +10 -9
- cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
- cirq/experiments/readout_confusion_matrix.py +73 -8
- cirq/experiments/readout_confusion_matrix_test.py +104 -1
- cirq/experiments/single_qubit_readout_calibration.py +8 -6
- cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
- cirq/experiments/t1_decay_experiment.py +4 -5
- cirq/experiments/t1_decay_experiment_test.py +1 -2
- cirq/experiments/t2_decay_experiment.py +0 -1
- cirq/experiments/t2_decay_experiment_test.py +1 -2
- cirq/experiments/two_qubit_xeb.py +157 -33
- cirq/experiments/two_qubit_xeb_test.py +38 -22
- cirq/experiments/xeb_fitting.py +99 -19
- cirq/experiments/xeb_fitting_test.py +64 -25
- cirq/experiments/xeb_sampling.py +14 -18
- cirq/experiments/xeb_simulation.py +4 -3
- cirq/experiments/xeb_simulation_test.py +20 -14
- cirq/experiments/z_phase_calibration.py +368 -0
- cirq/experiments/z_phase_calibration_test.py +241 -0
- cirq/interop/__init__.py +4 -1
- cirq/interop/quirk/__init__.py +7 -4
- cirq/interop/quirk/cells/__init__.py +17 -6
- cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
- cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
- cirq/interop/quirk/cells/cell.py +6 -6
- cirq/interop/quirk/cells/composite_cell.py +5 -5
- cirq/interop/quirk/cells/composite_cell_test.py +1 -1
- cirq/interop/quirk/cells/control_cells.py +1 -1
- cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
- cirq/interop/quirk/cells/ignored_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells_test.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
- cirq/interop/quirk/cells/measurement_cells.py +1 -1
- cirq/interop/quirk/cells/parse.py +8 -7
- cirq/interop/quirk/cells/parse_test.py +2 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/swap_cell_test.py +1 -1
- cirq/interop/quirk/cells/unsupported_cells.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +7 -7
- cirq/interop/quirk/url_to_circuit_test.py +1 -1
- cirq/ion/__init__.py +4 -2
- cirq/json_resolver_cache.py +15 -7
- cirq/linalg/__init__.py +62 -51
- cirq/linalg/combinators.py +4 -4
- cirq/linalg/combinators_test.py +4 -1
- cirq/linalg/decompositions.py +15 -40
- cirq/linalg/decompositions_test.py +16 -22
- cirq/linalg/diagonalize.py +1 -1
- cirq/linalg/diagonalize_test.py +1 -1
- cirq/linalg/operator_spaces.py +20 -4
- cirq/linalg/operator_spaces_test.py +15 -2
- cirq/linalg/predicates.py +3 -3
- cirq/linalg/predicates_test.py +1 -0
- cirq/linalg/tolerance.py +2 -2
- cirq/linalg/transformations.py +30 -12
- cirq/linalg/transformations_test.py +13 -0
- cirq/neutral_atoms/__init__.py +2 -2
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
- cirq/ops/__init__.py +172 -132
- cirq/ops/arithmetic_operation.py +2 -2
- cirq/ops/arithmetic_operation_test.py +2 -2
- cirq/ops/boolean_hamiltonian.py +3 -2
- cirq/ops/classically_controlled_operation.py +39 -12
- cirq/ops/classically_controlled_operation_test.py +147 -1
- cirq/ops/clifford_gate.py +38 -36
- cirq/ops/clifford_gate_test.py +75 -1
- cirq/ops/common_channels.py +16 -45
- cirq/ops/common_channels_test.py +10 -0
- cirq/ops/common_gate_families.py +1 -1
- cirq/ops/common_gate_families_test.py +1 -0
- cirq/ops/common_gates.py +48 -49
- cirq/ops/common_gates_test.py +18 -2
- cirq/ops/control_values.py +3 -3
- cirq/ops/control_values_test.py +2 -1
- cirq/ops/controlled_gate.py +36 -23
- cirq/ops/controlled_gate_test.py +70 -3
- cirq/ops/controlled_operation.py +6 -5
- cirq/ops/controlled_operation_test.py +7 -3
- cirq/ops/dense_pauli_string.py +11 -11
- cirq/ops/diagonal_gate.py +2 -2
- cirq/ops/diagonal_gate_test.py +1 -0
- cirq/ops/eigen_gate.py +16 -36
- cirq/ops/eigen_gate_test.py +60 -10
- cirq/ops/fourier_transform.py +1 -3
- cirq/ops/fourier_transform_test.py +2 -1
- cirq/ops/fsim_gate.py +42 -3
- cirq/ops/fsim_gate_test.py +21 -0
- cirq/ops/gate_operation.py +8 -8
- cirq/ops/gate_operation_test.py +4 -2
- cirq/ops/gateset_test.py +11 -2
- cirq/ops/global_phase_op.py +8 -7
- cirq/ops/global_phase_op_test.py +1 -1
- cirq/ops/greedy_qubit_manager_test.py +5 -0
- cirq/ops/identity.py +14 -4
- cirq/ops/identity_test.py +24 -0
- cirq/ops/kraus_channel.py +1 -0
- cirq/ops/kraus_channel_test.py +3 -1
- cirq/ops/linear_combinations.py +27 -21
- cirq/ops/linear_combinations_test.py +23 -4
- cirq/ops/matrix_gates.py +24 -8
- cirq/ops/measure_util.py +2 -2
- cirq/ops/measurement_gate.py +7 -4
- cirq/ops/measurement_gate_test.py +2 -1
- cirq/ops/mixed_unitary_channel.py +1 -0
- cirq/ops/mixed_unitary_channel_test.py +3 -1
- cirq/ops/named_qubit.py +8 -1
- cirq/ops/op_tree.py +3 -30
- cirq/ops/op_tree_test.py +4 -0
- cirq/ops/parallel_gate.py +2 -3
- cirq/ops/parallel_gate_test.py +2 -1
- cirq/ops/parity_gates.py +7 -8
- cirq/ops/parity_gates_test.py +1 -0
- cirq/ops/pauli_gates.py +5 -11
- cirq/ops/pauli_gates_test.py +1 -0
- cirq/ops/pauli_interaction_gate.py +11 -5
- cirq/ops/pauli_interaction_gate_test.py +2 -3
- cirq/ops/pauli_measurement_gate.py +6 -5
- cirq/ops/pauli_measurement_gate_test.py +1 -0
- cirq/ops/pauli_string.py +115 -130
- cirq/ops/pauli_string_phasor.py +21 -20
- cirq/ops/pauli_string_phasor_test.py +13 -3
- cirq/ops/pauli_string_raw_types.py +1 -0
- cirq/ops/pauli_string_test.py +192 -55
- cirq/ops/pauli_sum_exponential.py +3 -4
- cirq/ops/pauli_sum_exponential_test.py +0 -1
- cirq/ops/permutation_gate.py +2 -2
- cirq/ops/permutation_gate_test.py +1 -1
- cirq/ops/phased_iswap_gate.py +6 -7
- cirq/ops/phased_iswap_gate_test.py +21 -5
- cirq/ops/phased_x_gate.py +11 -25
- cirq/ops/phased_x_gate_test.py +19 -3
- cirq/ops/phased_x_z_gate.py +12 -11
- cirq/ops/projector.py +4 -5
- cirq/ops/qubit_manager.py +2 -1
- cirq/ops/qubit_manager_test.py +2 -1
- cirq/ops/qubit_order.py +1 -1
- cirq/ops/random_gate_channel.py +1 -1
- cirq/ops/random_gate_channel_test.py +0 -6
- cirq/ops/raw_types.py +146 -50
- cirq/ops/raw_types_test.py +37 -3
- cirq/ops/state_preparation_channel.py +2 -2
- cirq/ops/state_preparation_channel_test.py +2 -1
- cirq/ops/swap_gates.py +9 -4
- cirq/ops/three_qubit_gates.py +8 -8
- cirq/ops/three_qubit_gates_test.py +1 -0
- cirq/ops/two_qubit_diagonal_gate.py +4 -3
- cirq/ops/uniform_superposition_gate.py +4 -4
- cirq/ops/uniform_superposition_gate_test.py +1 -0
- cirq/ops/wait_gate.py +6 -8
- cirq/protocols/__init__.py +135 -83
- cirq/protocols/act_on_protocol.py +1 -1
- cirq/protocols/act_on_protocol_test.py +1 -1
- cirq/protocols/apply_channel_protocol.py +3 -3
- cirq/protocols/apply_mixture_protocol.py +15 -9
- cirq/protocols/apply_mixture_protocol_test.py +11 -0
- cirq/protocols/apply_unitary_protocol.py +2 -2
- cirq/protocols/apply_unitary_protocol_test.py +2 -1
- cirq/protocols/approximate_equality_protocol.py +7 -8
- cirq/protocols/approximate_equality_protocol_test.py +3 -1
- cirq/protocols/circuit_diagram_info_protocol.py +8 -6
- cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
- cirq/protocols/commutes_protocol.py +6 -6
- cirq/protocols/control_key_protocol.py +1 -1
- cirq/protocols/decompose_protocol.py +4 -5
- cirq/protocols/decompose_protocol_test.py +2 -1
- cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
- cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
- cirq/protocols/has_unitary_protocol.py +1 -1
- cirq/protocols/has_unitary_protocol_test.py +8 -7
- cirq/protocols/hash_from_pickle_test.py +120 -0
- cirq/protocols/inverse_protocol.py +1 -1
- cirq/protocols/json_serialization.py +14 -1
- cirq/protocols/json_serialization_test.py +28 -7
- cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
- cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
- cirq/protocols/json_test_data/Concat.json +19 -0
- cirq/protocols/json_test_data/Concat.repr +1 -0
- cirq/protocols/json_test_data/README.md +4 -2
- cirq/protocols/json_test_data/SympyCondition.json +60 -15
- cirq/protocols/json_test_data/SympyCondition.repr +4 -1
- cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
- cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
- cirq/protocols/json_test_data/__init__.py +1 -1
- cirq/protocols/json_test_data/sympy.And.json +13 -0
- cirq/protocols/json_test_data/sympy.And.repr +1 -0
- cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
- cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
- cirq/protocols/json_test_data/sympy.Not.json +9 -0
- cirq/protocols/json_test_data/sympy.Not.repr +1 -0
- cirq/protocols/json_test_data/sympy.Or.json +13 -0
- cirq/protocols/json_test_data/sympy.Or.repr +1 -0
- cirq/protocols/json_test_data/sympy.Xor.json +13 -0
- cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
- cirq/protocols/kraus_protocol.py +8 -8
- cirq/protocols/kraus_protocol_test.py +0 -1
- cirq/protocols/measurement_key_protocol.py +1 -1
- cirq/protocols/measurement_key_protocol_test.py +7 -7
- cirq/protocols/mixture_protocol.py +6 -4
- cirq/protocols/mixture_protocol_test.py +21 -13
- cirq/protocols/pauli_expansion_protocol.py +1 -0
- cirq/protocols/pow_protocol.py +1 -1
- cirq/protocols/qasm.py +25 -6
- cirq/protocols/qasm_test.py +17 -0
- cirq/protocols/qid_shape_protocol.py +2 -2
- cirq/protocols/resolve_parameters.py +2 -3
- cirq/protocols/resolve_parameters_test.py +2 -1
- cirq/protocols/trace_distance_bound.py +1 -1
- cirq/protocols/trace_distance_bound_test.py +1 -0
- cirq/protocols/unitary_protocol.py +3 -3
- cirq/protocols/unitary_protocol_test.py +1 -1
- cirq/qis/__init__.py +48 -35
- cirq/qis/channels_test.py +0 -9
- cirq/qis/clifford_tableau.py +46 -26
- cirq/qis/clifford_tableau_test.py +2 -1
- cirq/qis/entropy.py +115 -0
- cirq/qis/entropy_test.py +43 -0
- cirq/qis/measures.py +5 -4
- cirq/qis/measures_test.py +7 -0
- cirq/qis/noise_utils_test.py +4 -4
- cirq/qis/quantum_state_representation.py +1 -1
- cirq/qis/states.py +7 -7
- cirq/sim/__init__.py +55 -37
- cirq/sim/classical_simulator.py +7 -6
- cirq/sim/classical_simulator_test.py +3 -1
- cirq/sim/clifford/__init__.py +17 -9
- cirq/sim/clifford/clifford_simulator.py +5 -4
- cirq/sim/clifford/clifford_simulator_test.py +32 -9
- cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
- cirq/sim/density_matrix_simulator.py +3 -2
- cirq/sim/density_matrix_simulator_test.py +12 -4
- cirq/sim/density_matrix_utils.py +1 -1
- cirq/sim/mux.py +2 -2
- cirq/sim/simulation_state.py +4 -5
- cirq/sim/simulation_state_base.py +2 -2
- cirq/sim/simulation_state_test.py +1 -1
- cirq/sim/simulation_utils.py +3 -1
- cirq/sim/simulation_utils_test.py +2 -3
- cirq/sim/simulator.py +7 -6
- cirq/sim/simulator_base.py +5 -5
- cirq/sim/simulator_test.py +14 -3
- cirq/sim/sparse_simulator.py +4 -3
- cirq/sim/sparse_simulator_test.py +17 -9
- cirq/sim/state_vector.py +2 -2
- cirq/sim/state_vector_simulation_state_test.py +1 -1
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/sim/state_vector_test.py +27 -32
- cirq/study/__init__.py +27 -21
- cirq/study/flatten_expressions.py +5 -6
- cirq/study/flatten_expressions_test.py +1 -1
- cirq/study/resolver.py +14 -11
- cirq/study/resolver_test.py +10 -1
- cirq/study/result.py +3 -3
- cirq/study/sweepable.py +15 -9
- cirq/study/sweepable_test.py +27 -0
- cirq/study/sweeps.py +65 -10
- cirq/study/sweeps_test.py +123 -0
- cirq/testing/__init__.py +86 -57
- cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
- cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
- cirq/testing/circuit_compare.py +3 -4
- cirq/testing/circuit_compare_test.py +7 -8
- cirq/testing/consistent_act_on.py +3 -3
- cirq/testing/consistent_channels_test.py +2 -1
- cirq/testing/consistent_controlled_gate_op.py +3 -2
- cirq/testing/consistent_controlled_gate_op_test.py +2 -3
- cirq/testing/consistent_decomposition.py +1 -1
- cirq/testing/consistent_decomposition_test.py +1 -2
- cirq/testing/consistent_pauli_expansion_test.py +1 -1
- cirq/testing/consistent_phase_by.py +1 -1
- cirq/testing/consistent_phase_by_test.py +1 -2
- cirq/testing/consistent_protocols.py +11 -11
- cirq/testing/consistent_protocols_test.py +4 -5
- cirq/testing/consistent_qasm.py +8 -12
- cirq/testing/consistent_qasm_test.py +1 -1
- cirq/testing/consistent_resolve_parameters.py +2 -1
- cirq/testing/consistent_specified_has_unitary_test.py +1 -1
- cirq/testing/consistent_unitary.py +3 -1
- cirq/testing/consistent_unitary_test.py +3 -3
- cirq/testing/devices.py +1 -1
- cirq/testing/devices_test.py +1 -0
- cirq/testing/equals_tester.py +2 -4
- cirq/testing/equals_tester_test.py +6 -5
- cirq/testing/equivalent_basis_map.py +1 -0
- cirq/testing/equivalent_basis_map_test.py +0 -1
- cirq/testing/gate_features_test.py +5 -0
- cirq/testing/json.py +4 -4
- cirq/testing/lin_alg_utils_test.py +1 -1
- cirq/testing/order_tester.py +1 -1
- cirq/testing/order_tester_test.py +1 -1
- cirq/testing/pytest_utils.py +57 -0
- cirq/testing/pytest_utils_test.py +35 -0
- cirq/testing/random_circuit.py +2 -2
- cirq/testing/random_circuit_test.py +2 -2
- cirq/testing/routing_devices_test.py +2 -1
- cirq/testing/sample_circuits.py +1 -1
- cirq/testing/sample_gates.py +5 -4
- cirq/testing/sample_gates_test.py +2 -2
- cirq/transformers/__init__.py +101 -82
- cirq/transformers/align.py +12 -1
- cirq/transformers/align_test.py +13 -0
- cirq/transformers/analytical_decompositions/__init__.py +27 -24
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
- cirq/transformers/drop_empty_moments.py +1 -0
- cirq/transformers/drop_negligible_operations.py +1 -0
- cirq/transformers/dynamical_decoupling.py +255 -43
- cirq/transformers/dynamical_decoupling_test.py +730 -17
- cirq/transformers/eject_phased_paulis.py +29 -15
- cirq/transformers/eject_phased_paulis_test.py +3 -8
- cirq/transformers/eject_z.py +3 -2
- cirq/transformers/eject_z_test.py +3 -3
- cirq/transformers/gauge_compiling/__init__.py +25 -9
- cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
- cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
- cirq/transformers/heuristic_decompositions/__init__.py +3 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
- cirq/transformers/insertion_sort.py +64 -0
- cirq/transformers/insertion_sort_test.py +34 -0
- cirq/transformers/measurement_transformers.py +14 -1
- cirq/transformers/measurement_transformers_test.py +35 -0
- cirq/transformers/merge_k_qubit_gates.py +2 -2
- cirq/transformers/merge_single_qubit_gates.py +1 -1
- cirq/transformers/merge_single_qubit_gates_test.py +1 -1
- cirq/transformers/noise_adding.py +115 -0
- cirq/transformers/noise_adding_test.py +54 -0
- cirq/transformers/optimize_for_target_gateset.py +1 -1
- cirq/transformers/optimize_for_target_gateset_test.py +3 -2
- cirq/transformers/qubit_management_transformers.py +1 -1
- cirq/transformers/randomized_measurements.py +171 -0
- cirq/transformers/randomized_measurements_test.py +68 -0
- cirq/transformers/routing/__init__.py +14 -5
- cirq/transformers/routing/initial_mapper.py +1 -1
- cirq/transformers/routing/initial_mapper_test.py +1 -0
- cirq/transformers/routing/line_initial_mapper.py +3 -2
- cirq/transformers/routing/mapping_manager.py +2 -2
- cirq/transformers/routing/mapping_manager_test.py +2 -2
- cirq/transformers/routing/route_circuit_cqc.py +3 -2
- cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
- cirq/transformers/routing/visualize_routed_circuit.py +1 -0
- cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
- cirq/transformers/stratify.py +2 -2
- cirq/transformers/synchronize_terminal_measurements.py +2 -1
- cirq/transformers/target_gatesets/__init__.py +7 -5
- cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
- cirq/transformers/target_gatesets/cz_gateset.py +5 -1
- cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
- cirq/transformers/transformer_api.py +5 -4
- cirq/transformers/transformer_api_test.py +11 -3
- cirq/transformers/transformer_primitives.py +9 -31
- cirq/transformers/transformer_primitives_test.py +6 -5
- cirq/value/__init__.py +51 -30
- cirq/value/abc_alt.py +1 -2
- cirq/value/angle.py +2 -0
- cirq/value/classical_data.py +1 -0
- cirq/value/condition.py +149 -3
- cirq/value/condition_test.py +254 -0
- cirq/value/digits.py +1 -1
- cirq/value/duration.py +4 -4
- cirq/value/duration_test.py +2 -1
- cirq/value/linear_dict.py +85 -24
- cirq/value/linear_dict_test.py +94 -3
- cirq/value/measurement_key.py +9 -2
- cirq/value/periodic_value.py +2 -3
- cirq/value/periodic_value_test.py +5 -0
- cirq/value/probability.py +1 -0
- cirq/value/random_state.py +1 -1
- cirq/value/timestamp.py +2 -4
- cirq/value/timestamp_test.py +2 -1
- cirq/value/type_alias.py +2 -2
- cirq/value/value_equality_attr.py +14 -2
- cirq/value/value_equality_attr_test.py +1 -1
- cirq/vis/__init__.py +9 -6
- cirq/vis/density_matrix.py +1 -1
- cirq/vis/density_matrix_test.py +2 -5
- cirq/vis/heatmap.py +49 -12
- cirq/vis/heatmap_test.py +168 -4
- cirq/vis/histogram.py +1 -1
- cirq/vis/histogram_test.py +1 -2
- cirq/vis/state_histogram.py +7 -5
- cirq/vis/state_histogram_test.py +2 -2
- cirq/work/__init__.py +19 -13
- cirq/work/collector.py +2 -2
- cirq/work/observable_grouping.py +2 -2
- cirq/work/observable_measurement.py +3 -3
- cirq/work/observable_measurement_data.py +5 -2
- cirq/work/observable_measurement_test.py +8 -8
- cirq/work/observable_readout_calibration.py +2 -2
- cirq/work/observable_readout_calibration_test.py +2 -1
- cirq/work/observable_settings.py +8 -7
- cirq/work/observable_settings_test.py +3 -2
- cirq/work/pauli_sum_collector.py +1 -1
- cirq/work/sampler.py +8 -20
- cirq/work/sampler_test.py +4 -3
- cirq/work/zeros_sampler.py +1 -1
- cirq_core-1.5.0.dist-info/METADATA +125 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
- cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
- cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
- cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
- cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -19,30 +19,46 @@ Based on:
|
|
|
19
19
|
Synthesis of Quantum Logic Circuits. Tech. rep. 2006,
|
|
20
20
|
https://arxiv.org/abs/quant-ph/0406176
|
|
21
21
|
"""
|
|
22
|
-
from typing import
|
|
23
|
-
|
|
24
|
-
from scipy.linalg import cossin
|
|
22
|
+
from typing import Callable, Iterable, List, TYPE_CHECKING
|
|
25
23
|
|
|
26
24
|
import numpy as np
|
|
25
|
+
from scipy.linalg import cossin
|
|
27
26
|
|
|
28
27
|
from cirq import ops
|
|
28
|
+
from cirq.circuits.frozen_circuit import FrozenCircuit
|
|
29
29
|
from cirq.linalg import decompositions, predicates
|
|
30
|
+
from cirq.protocols import unitary_protocol
|
|
31
|
+
from cirq.transformers.analytical_decompositions.three_qubit_decomposition import (
|
|
32
|
+
three_qubit_matrix_to_operations,
|
|
33
|
+
)
|
|
34
|
+
from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
|
|
35
|
+
two_qubit_matrix_to_cz_operations,
|
|
36
|
+
)
|
|
30
37
|
|
|
31
38
|
if TYPE_CHECKING:
|
|
32
39
|
import cirq
|
|
33
|
-
from cirq.ops import op_tree
|
|
34
40
|
|
|
35
41
|
|
|
36
|
-
def quantum_shannon_decomposition(
|
|
37
|
-
|
|
42
|
+
def quantum_shannon_decomposition(
|
|
43
|
+
qubits: 'List[cirq.Qid]', u: np.ndarray, atol: float = 1e-8
|
|
44
|
+
) -> Iterable['cirq.Operation']:
|
|
45
|
+
"""Decomposes n-qubit unitary 1-q, 2-q and GlobalPhase gates, preserving global phase.
|
|
46
|
+
|
|
47
|
+
The gates used are CX/YPow/ZPow/CNOT/GlobalPhase/CZ/PhasedXZGate/PhasedXPowGate.
|
|
38
48
|
|
|
39
49
|
The algorithm is described in Shende et al.:
|
|
40
50
|
Synthesis of Quantum Logic Circuits. Tech. rep. 2006,
|
|
41
51
|
https://arxiv.org/abs/quant-ph/0406176
|
|
42
52
|
|
|
53
|
+
Note: Shannon decomposition is sensitive to the numerical accuracy of doing eigendecomposition.
|
|
54
|
+
Eigendecomposition is obtained using `np.linalg.eig` and the resulting difference between
|
|
55
|
+
the input and output unitary is heavily affected by the accuracy of `np.linalg.eig`.
|
|
56
|
+
|
|
57
|
+
|
|
43
58
|
Args:
|
|
44
59
|
qubits: List of qubits in order of significance
|
|
45
60
|
u: Numpy array for unitary matrix representing gate to be decomposed
|
|
61
|
+
atol: Absolute tolerance of floating point checks.
|
|
46
62
|
|
|
47
63
|
Calls:
|
|
48
64
|
(Base Case)
|
|
@@ -62,7 +78,7 @@ def quantum_shannon_decomposition(qubits: 'List[cirq.Qid]', u: np.ndarray) -> 'o
|
|
|
62
78
|
ValueError: If the u matrix is non-unitary
|
|
63
79
|
ValueError: If the u matrix is not of shape (2^n,2^n)
|
|
64
80
|
"""
|
|
65
|
-
if not predicates.is_unitary(u): # Check that u is unitary
|
|
81
|
+
if not predicates.is_unitary(u, atol=atol): # Check that u is unitary
|
|
66
82
|
raise ValueError(
|
|
67
83
|
"Expected input matrix u to be unitary, \
|
|
68
84
|
but it fails cirq.is_unitary check"
|
|
@@ -80,6 +96,32 @@ def quantum_shannon_decomposition(qubits: 'List[cirq.Qid]', u: np.ndarray) -> 'o
|
|
|
80
96
|
yield from _single_qubit_decomposition(qubits[0], u)
|
|
81
97
|
return
|
|
82
98
|
|
|
99
|
+
if n == 4:
|
|
100
|
+
operations = tuple(
|
|
101
|
+
two_qubit_matrix_to_cz_operations(
|
|
102
|
+
qubits[0], qubits[1], u, allow_partial_czs=True, clean_operations=True, atol=atol
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
yield from operations
|
|
106
|
+
i, j = np.unravel_index(np.argmax(np.abs(u)), u.shape)
|
|
107
|
+
new_unitary = unitary_protocol.unitary(FrozenCircuit.from_moments(*operations))
|
|
108
|
+
global_phase = np.angle(u[i, j]) - np.angle(new_unitary[i, j])
|
|
109
|
+
if np.abs(global_phase) > 1e-9:
|
|
110
|
+
yield ops.global_phase_operation(np.exp(1j * global_phase))
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
if n == 8:
|
|
114
|
+
operations = tuple(
|
|
115
|
+
three_qubit_matrix_to_operations(qubits[0], qubits[1], qubits[2], u, atol=atol)
|
|
116
|
+
)
|
|
117
|
+
yield from operations
|
|
118
|
+
i, j = np.unravel_index(np.argmax(np.abs(u)), u.shape)
|
|
119
|
+
new_unitary = unitary_protocol.unitary(FrozenCircuit.from_moments(*operations))
|
|
120
|
+
global_phase = np.angle(u[i, j]) - np.angle(new_unitary[i, j])
|
|
121
|
+
if np.abs(global_phase) > 1e-9:
|
|
122
|
+
yield ops.global_phase_operation(np.exp(1j * global_phase))
|
|
123
|
+
return
|
|
124
|
+
|
|
83
125
|
# Perform a cosine-sine (linalg) decomposition on u
|
|
84
126
|
# X = [ u1 , 0 ] [ cos(theta) , -sin(theta) ] [ v1 , 0 ]
|
|
85
127
|
# [ 0 , u2 ] [ sin(theta) , cos(theta) ] [ 0 , v2 ]
|
|
@@ -97,7 +139,7 @@ def quantum_shannon_decomposition(qubits: 'List[cirq.Qid]', u: np.ndarray) -> 'o
|
|
|
97
139
|
yield from _msb_demuxer(qubits, u1, u2)
|
|
98
140
|
|
|
99
141
|
|
|
100
|
-
def _single_qubit_decomposition(qubit: 'cirq.Qid', u: np.ndarray) -> '
|
|
142
|
+
def _single_qubit_decomposition(qubit: 'cirq.Qid', u: np.ndarray) -> Iterable['cirq.Operation']:
|
|
101
143
|
"""Decomposes single-qubit gate, and returns list of operations, keeping phase invariant.
|
|
102
144
|
|
|
103
145
|
Args:
|
|
@@ -108,22 +150,41 @@ def _single_qubit_decomposition(qubit: 'cirq.Qid', u: np.ndarray) -> 'op_tree.Op
|
|
|
108
150
|
A single operation from OP TREE of 3 operations (rz,ry,ZPowGate)
|
|
109
151
|
"""
|
|
110
152
|
# Perform native ZYZ decomposition
|
|
111
|
-
phi_0, phi_1, phi_2 =
|
|
153
|
+
phi_0, phi_1, phi_2 = np.array(
|
|
154
|
+
decompositions.deconstruct_single_qubit_matrix_into_angles(u)
|
|
155
|
+
) % (2 * np.pi)
|
|
112
156
|
|
|
113
157
|
# Determine global phase picked up
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
158
|
+
global_phase = np.angle(u[0, 0]) + phi_0 / 2 + phi_2 / 2
|
|
159
|
+
if np.abs(u[0, 0]) < 1e-9:
|
|
160
|
+
global_phase = np.angle(u[1, 0]) + phi_0 / 2 - phi_2 / 2
|
|
161
|
+
|
|
162
|
+
if np.abs(phi_2) > 1e-18:
|
|
163
|
+
# Append first two operations operations
|
|
164
|
+
yield ops.rz(phi_0).on(qubit)
|
|
165
|
+
yield ops.ry(phi_1).on(qubit)
|
|
166
|
+
|
|
167
|
+
# Append third operation with global phase added
|
|
168
|
+
yield ops.ZPowGate(exponent=phi_2 / np.pi, global_shift=global_phase / phi_2 - 0.5)(qubit)
|
|
169
|
+
elif np.abs(phi_1) > 1e-18:
|
|
170
|
+
# Just a Z -> Y rotation so we attach the global phase to the Y rotation.
|
|
171
|
+
if np.abs(phi_0) > 1e-18:
|
|
172
|
+
yield ops.rz(phi_0)(qubit)
|
|
173
|
+
yield ops.YPowGate(exponent=phi_1 / np.pi, global_shift=global_phase / phi_1 - 0.5)(qubit)
|
|
174
|
+
elif np.abs(phi_0) > 1e-18:
|
|
175
|
+
# Just an Rz with a potential global phase.
|
|
176
|
+
yield ops.ZPowGate(exponent=phi_0 / np.pi, global_shift=global_phase / phi_0 - 0.5)(qubit)
|
|
177
|
+
elif np.abs(global_phase) > 1e-18:
|
|
178
|
+
# Global Phase.
|
|
179
|
+
yield ops.global_phase_operation(np.exp(1j * global_phase))
|
|
180
|
+
else:
|
|
181
|
+
# Identity.
|
|
182
|
+
return
|
|
122
183
|
|
|
123
184
|
|
|
124
185
|
def _msb_demuxer(
|
|
125
186
|
demux_qubits: 'List[cirq.Qid]', u1: np.ndarray, u2: np.ndarray
|
|
126
|
-
) -> '
|
|
187
|
+
) -> Iterable['cirq.Operation']:
|
|
127
188
|
"""Demultiplexes a unitary matrix that is multiplexed in its most-significant-qubit.
|
|
128
189
|
|
|
129
190
|
Decomposition structure:
|
|
@@ -146,8 +207,21 @@ def _msb_demuxer(
|
|
|
146
207
|
Yields: Single operation from OP TREE of 2-qubit and 1-qubit operations
|
|
147
208
|
"""
|
|
148
209
|
# Perform a diagonalization to find values
|
|
210
|
+
u1 = u1.astype(np.complex128)
|
|
211
|
+
u2 = u2.astype(np.complex128)
|
|
149
212
|
u = u1 @ u2.T.conjugate()
|
|
150
|
-
|
|
213
|
+
if predicates.is_hermitian(u):
|
|
214
|
+
# If `u` is hermitian, use the more accurate `eigh` method.
|
|
215
|
+
dsquared, V = np.linalg.eigh(u)
|
|
216
|
+
else:
|
|
217
|
+
dsquared, V = np.linalg.eig(u)
|
|
218
|
+
# Use Gram–Schmidt to obtain orthonormal eigenvectors for each of the subspaces.
|
|
219
|
+
for i in range(V.shape[0]):
|
|
220
|
+
for j in range(i):
|
|
221
|
+
if np.abs(dsquared[i] - dsquared[j]) < 1e-9:
|
|
222
|
+
V[:, i] -= np.dot(V[:, j].conj(), V[:, i]) * V[:, j]
|
|
223
|
+
V[:, i] /= np.linalg.norm(V[:, i]) # normalize.
|
|
224
|
+
dsquared = dsquared.astype(np.complex128)
|
|
151
225
|
d = np.sqrt(dsquared)
|
|
152
226
|
D = np.diag(d)
|
|
153
227
|
W = D @ V.T.conjugate() @ u2
|
|
@@ -155,7 +229,7 @@ def _msb_demuxer(
|
|
|
155
229
|
# Last term is given by ( I ⊗ W ), demultiplexed
|
|
156
230
|
# Remove most-significant (demuxed) control-qubit
|
|
157
231
|
# Yield operations for QSD on W
|
|
158
|
-
yield from quantum_shannon_decomposition(demux_qubits[1:], W)
|
|
232
|
+
yield from quantum_shannon_decomposition(demux_qubits[1:], W, atol=1e-6)
|
|
159
233
|
|
|
160
234
|
# Use complex phase of d_i to give theta_i (so d_i* gives -theta_i)
|
|
161
235
|
# Observe that middle part looks like Σ_i( Rz(theta_i)⊗|i><i| )
|
|
@@ -163,7 +237,7 @@ def _msb_demuxer(
|
|
|
163
237
|
yield from _multiplexed_cossin(demux_qubits, -np.angle(d), ops.rz)
|
|
164
238
|
|
|
165
239
|
# Yield operations for QSD on V
|
|
166
|
-
yield from quantum_shannon_decomposition(demux_qubits[1:], V)
|
|
240
|
+
yield from quantum_shannon_decomposition(demux_qubits[1:], V, atol=1e-6)
|
|
167
241
|
|
|
168
242
|
|
|
169
243
|
def _nth_gray(n: int) -> int:
|
|
@@ -173,7 +247,7 @@ def _nth_gray(n: int) -> int:
|
|
|
173
247
|
|
|
174
248
|
def _multiplexed_cossin(
|
|
175
249
|
cossin_qubits: 'List[cirq.Qid]', angles: List[float], rot_func: Callable = ops.ry
|
|
176
|
-
) -> '
|
|
250
|
+
) -> Iterable['cirq.Operation']:
|
|
177
251
|
"""Performs a multiplexed rotation over all qubits in this unitary matrix,
|
|
178
252
|
|
|
179
253
|
Uses ry and rz multiplexing for quantum shannon decomposition
|
|
@@ -223,8 +297,9 @@ def _multiplexed_cossin(
|
|
|
223
297
|
# so introduce max function
|
|
224
298
|
select_qubit = max(-select_qubit - 1, -len(control_qubits))
|
|
225
299
|
|
|
226
|
-
|
|
227
|
-
|
|
300
|
+
if np.abs(rotation) > 1e-9:
|
|
301
|
+
# Add a rotation on the main qubit
|
|
302
|
+
yield rot_func(rotation).on(main_qubit)
|
|
228
303
|
|
|
229
304
|
# Add a CNOT from the select qubit to the main qubit
|
|
230
305
|
yield ops.CNOT(control_qubits[select_qubit], main_qubit)
|
|
@@ -12,21 +12,22 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
import numpy as np
|
|
16
|
+
import pytest
|
|
17
|
+
from scipy.stats import unitary_group
|
|
18
|
+
|
|
15
19
|
import cirq
|
|
16
20
|
from cirq.ops import common_gates
|
|
17
21
|
from cirq.transformers.analytical_decompositions.quantum_shannon_decomposition import (
|
|
22
|
+
_msb_demuxer,
|
|
18
23
|
_multiplexed_cossin,
|
|
19
24
|
_nth_gray,
|
|
20
|
-
_msb_demuxer,
|
|
21
25
|
_single_qubit_decomposition,
|
|
22
26
|
quantum_shannon_decomposition,
|
|
23
27
|
)
|
|
24
28
|
|
|
25
|
-
import pytest
|
|
26
|
-
import numpy as np
|
|
27
|
-
from scipy.stats import unitary_group
|
|
28
|
-
|
|
29
29
|
|
|
30
|
+
@pytest.mark.xfail(reason='#6765')
|
|
30
31
|
@pytest.mark.parametrize('n_qubits', list(range(1, 8)))
|
|
31
32
|
def test_random_qsd_n_qubit(n_qubits):
|
|
32
33
|
U = unitary_group.rvs(2**n_qubits)
|
|
@@ -34,9 +35,8 @@ def test_random_qsd_n_qubit(n_qubits):
|
|
|
34
35
|
circuit = cirq.Circuit(quantum_shannon_decomposition(qubits, U))
|
|
35
36
|
# Test return is equal to inital unitary
|
|
36
37
|
assert cirq.approx_eq(U, circuit.unitary(), atol=1e-9)
|
|
37
|
-
# Test all operations
|
|
38
|
-
|
|
39
|
-
assert all(isinstance(op.gate, gates) for op in circuit.all_operations())
|
|
38
|
+
# Test all operations have at most 2 qubits.
|
|
39
|
+
assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def test_qsd_n_qubit_errors():
|
|
@@ -53,9 +53,8 @@ def test_random_single_qubit_decomposition():
|
|
|
53
53
|
circuit = cirq.Circuit(_single_qubit_decomposition(qubit, U))
|
|
54
54
|
# Test return is equal to inital unitary
|
|
55
55
|
assert cirq.approx_eq(U, circuit.unitary(), atol=1e-9)
|
|
56
|
-
# Test all operations
|
|
57
|
-
|
|
58
|
-
assert all(isinstance(op.gate, gates) for op in circuit.all_operations())
|
|
56
|
+
# Test all operations have at most 2 qubits.
|
|
57
|
+
assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
|
|
59
58
|
|
|
60
59
|
|
|
61
60
|
def test_msb_demuxer():
|
|
@@ -66,9 +65,8 @@ def test_msb_demuxer():
|
|
|
66
65
|
circuit = cirq.Circuit(_msb_demuxer(qubits, U1, U2))
|
|
67
66
|
# Test return is equal to inital unitary
|
|
68
67
|
assert cirq.approx_eq(U_full, circuit.unitary(), atol=1e-9)
|
|
69
|
-
# Test all operations
|
|
70
|
-
|
|
71
|
-
assert all(isinstance(op.gate, gates) for op in circuit.all_operations())
|
|
68
|
+
# Test all operations have at most 2 qubits.
|
|
69
|
+
assert all(cirq.num_qubits(op) <= 2 for op in circuit.all_operations())
|
|
72
70
|
|
|
73
71
|
|
|
74
72
|
def test_multiplexed_cossin():
|
|
@@ -110,3 +108,96 @@ def test_multiplexed_cossin():
|
|
|
110
108
|
)
|
|
111
109
|
def test_nth_gray(n, gray):
|
|
112
110
|
assert _nth_gray(n) == gray
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_ghz_circuit_decomposes():
|
|
114
|
+
# Test case from #6725
|
|
115
|
+
ghz_circuit = cirq.Circuit(cirq.H(cirq.q(0)), cirq.CNOT(cirq.q(0), cirq.q(1)))
|
|
116
|
+
ghz_unitary = cirq.unitary(ghz_circuit)
|
|
117
|
+
decomposed_circuit = cirq.Circuit(
|
|
118
|
+
quantum_shannon_decomposition(cirq.LineQubit.range(2), ghz_unitary)
|
|
119
|
+
)
|
|
120
|
+
new_unitary = cirq.unitary(decomposed_circuit)
|
|
121
|
+
np.testing.assert_allclose(new_unitary, ghz_unitary, atol=1e-6)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_qft_decomposes():
|
|
125
|
+
# Test case from #6666
|
|
126
|
+
qs = cirq.LineQubit.range(4)
|
|
127
|
+
qft_circuit = cirq.Circuit(cirq.qft(*qs))
|
|
128
|
+
qft_unitary = cirq.unitary(qft_circuit)
|
|
129
|
+
decomposed_circuit = cirq.Circuit(quantum_shannon_decomposition(qs, qft_unitary))
|
|
130
|
+
new_unitary = cirq.unitary(decomposed_circuit)
|
|
131
|
+
np.testing.assert_allclose(new_unitary, qft_unitary, atol=1e-6)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# Cliffords test the different corner cases of the ZYZ decomposition.
|
|
135
|
+
@pytest.mark.parametrize(
|
|
136
|
+
['gate', 'num_ops'],
|
|
137
|
+
[
|
|
138
|
+
(cirq.I, 0),
|
|
139
|
+
(cirq.X, 2), # rz & ry
|
|
140
|
+
(cirq.Y, 1), # ry
|
|
141
|
+
(cirq.Z, 1), # rz
|
|
142
|
+
(cirq.H, 2), # rz & ry
|
|
143
|
+
(cirq.S, 1), # rz & ry
|
|
144
|
+
],
|
|
145
|
+
)
|
|
146
|
+
def test_cliffords(gate, num_ops):
|
|
147
|
+
desired_unitary = cirq.unitary(gate)
|
|
148
|
+
shannon_circuit = cirq.Circuit(quantum_shannon_decomposition((cirq.q(0),), desired_unitary))
|
|
149
|
+
new_unitary = cirq.unitary(shannon_circuit)
|
|
150
|
+
assert len([*shannon_circuit.all_operations()]) == num_ops
|
|
151
|
+
if num_ops:
|
|
152
|
+
np.testing.assert_allclose(new_unitary, desired_unitary)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@pytest.mark.parametrize('gate', [cirq.X, cirq.Y, cirq.Z, cirq.H, cirq.S])
|
|
156
|
+
def test_cliffords_with_global_phase(gate):
|
|
157
|
+
global_phase = np.exp(1j * np.random.choice(np.linspace(0.1, 2 * np.pi, 10)))
|
|
158
|
+
desired_unitary = cirq.unitary(gate) * global_phase
|
|
159
|
+
shannon_circuit = cirq.Circuit(quantum_shannon_decomposition((cirq.q(0),), desired_unitary))
|
|
160
|
+
new_unitary = cirq.unitary(shannon_circuit)
|
|
161
|
+
np.testing.assert_allclose(new_unitary, desired_unitary)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def test_global_phase():
|
|
165
|
+
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
166
|
+
shannon_circuit = cirq.Circuit(
|
|
167
|
+
quantum_shannon_decomposition((cirq.q(0),), np.eye(2) * global_phase)
|
|
168
|
+
)
|
|
169
|
+
new_unitary = cirq.unitary(shannon_circuit)
|
|
170
|
+
np.testing.assert_allclose(np.diag(new_unitary), global_phase)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@pytest.mark.parametrize('gate', [cirq.CZ, cirq.CNOT, cirq.XX, cirq.YY, cirq.ZZ])
|
|
174
|
+
def test_two_qubit_gate(gate):
|
|
175
|
+
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
176
|
+
desired_unitary = cirq.unitary(gate) * global_phase
|
|
177
|
+
shannon_circuit = cirq.Circuit(
|
|
178
|
+
quantum_shannon_decomposition(cirq.LineQubit.range(2), desired_unitary)
|
|
179
|
+
)
|
|
180
|
+
new_unitary = cirq.unitary(shannon_circuit)
|
|
181
|
+
np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@pytest.mark.parametrize('gate', [cirq.CCNOT, cirq.qft(*cirq.LineQubit.range(3))])
|
|
185
|
+
def test_three_qubit_gate(gate):
|
|
186
|
+
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
187
|
+
desired_unitary = cirq.unitary(gate) * global_phase
|
|
188
|
+
shannon_circuit = cirq.Circuit(
|
|
189
|
+
quantum_shannon_decomposition(cirq.LineQubit.range(3), desired_unitary)
|
|
190
|
+
)
|
|
191
|
+
new_unitary = cirq.unitary(shannon_circuit)
|
|
192
|
+
np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@pytest.mark.xfail(reason='#6765')
|
|
196
|
+
def test_qft5():
|
|
197
|
+
global_phase = np.exp(1j * np.random.choice(np.linspace(0, 2 * np.pi, 10)))
|
|
198
|
+
desired_unitary = cirq.unitary(cirq.qft(*cirq.LineQubit.range(5))) * global_phase
|
|
199
|
+
shannon_circuit = cirq.Circuit(
|
|
200
|
+
quantum_shannon_decomposition(cirq.LineQubit.range(5), desired_unitary)
|
|
201
|
+
)
|
|
202
|
+
new_unitary = cirq.unitary(shannon_circuit)
|
|
203
|
+
np.testing.assert_allclose(new_unitary, desired_unitary, atol=1e-6)
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
"""Analytical decompositions for 2-qubit unitaries when one input qubit is in the |0> state."""
|
|
16
16
|
from typing import List, TYPE_CHECKING
|
|
17
|
+
|
|
17
18
|
import numpy as np
|
|
18
19
|
|
|
19
20
|
from cirq import ops
|
|
20
|
-
|
|
21
21
|
from cirq.transformers.analytical_decompositions import two_qubit_to_cz
|
|
22
22
|
|
|
23
23
|
if TYPE_CHECKING:
|
|
@@ -14,18 +14,17 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility methods for decomposing three-qubit unitaries."""
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import List, Optional, Sequence, Tuple, Union
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
|
|
21
21
|
import cirq
|
|
22
|
-
from cirq import ops
|
|
23
|
-
from cirq import transformers as opt
|
|
22
|
+
from cirq import ops, transformers as opt
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
def three_qubit_matrix_to_operations(
|
|
27
26
|
q0: ops.Qid, q1: ops.Qid, q2: ops.Qid, u: np.ndarray, atol: float = 1e-8
|
|
28
|
-
) ->
|
|
27
|
+
) -> List[ops.Operation]:
|
|
29
28
|
"""Returns operations for a 3 qubit unitary.
|
|
30
29
|
|
|
31
30
|
The algorithm is described in Shende et al.:
|
|
@@ -22,9 +22,9 @@ from scipy.linalg import block_diag
|
|
|
22
22
|
|
|
23
23
|
import cirq
|
|
24
24
|
from cirq.transformers.analytical_decompositions.three_qubit_decomposition import (
|
|
25
|
-
_multiplexed_angles,
|
|
26
25
|
_cs_to_ops,
|
|
27
26
|
_middle_multiplexor_to_ops,
|
|
27
|
+
_multiplexed_angles,
|
|
28
28
|
_two_qubit_multiplexor_to_ops,
|
|
29
29
|
)
|
|
30
30
|
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
"""Utility methods for efficiently preparing two qubit states."""
|
|
16
16
|
|
|
17
17
|
from typing import List, TYPE_CHECKING
|
|
18
|
+
|
|
18
19
|
import numpy as np
|
|
19
20
|
|
|
20
|
-
from cirq import ops, qis
|
|
21
|
+
from cirq import circuits, ops, qis
|
|
21
22
|
from cirq.transformers.analytical_decompositions import single_qubit_decompositions
|
|
22
23
|
|
|
23
24
|
if TYPE_CHECKING:
|
|
@@ -14,18 +14,17 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility methods for decomposing two-qubit unitaries into CZ gates."""
|
|
16
16
|
|
|
17
|
-
from typing import Iterable, List, Sequence, Tuple,
|
|
17
|
+
from typing import cast, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
|
|
21
|
+
from cirq import circuits, linalg, ops, protocols
|
|
21
22
|
from cirq.linalg import predicates
|
|
22
|
-
from cirq.linalg.decompositions import
|
|
23
|
-
|
|
24
|
-
from cirq import ops, linalg, protocols, circuits
|
|
23
|
+
from cirq.linalg.decompositions import extract_right_diag, num_cnots_required
|
|
25
24
|
from cirq.transformers.analytical_decompositions import single_qubit_decompositions
|
|
26
|
-
from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phased_x_and_z
|
|
27
|
-
from cirq.transformers.eject_z import eject_z
|
|
28
25
|
from cirq.transformers.eject_phased_paulis import eject_phased_paulis
|
|
26
|
+
from cirq.transformers.eject_z import eject_z
|
|
27
|
+
from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phased_x_and_z
|
|
29
28
|
|
|
30
29
|
if TYPE_CHECKING:
|
|
31
30
|
import cirq
|
|
@@ -20,12 +20,12 @@ import pytest
|
|
|
20
20
|
|
|
21
21
|
import cirq
|
|
22
22
|
from cirq import value
|
|
23
|
+
from cirq.testing import random_two_qubit_circuit_with_czs
|
|
23
24
|
from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
|
|
24
|
-
_parity_interaction,
|
|
25
25
|
_is_trivial_angle,
|
|
26
|
+
_parity_interaction,
|
|
26
27
|
two_qubit_matrix_to_diagonal_and_cz_operations,
|
|
27
28
|
)
|
|
28
|
-
from cirq.testing import random_two_qubit_circuit_with_czs
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
@pytest.mark.parametrize(
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility methods for decomposing two-qubit unitaries into FSim gates."""
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import Iterable, Iterator, List, Optional, Sequence, TYPE_CHECKING, Union
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
|
|
@@ -22,13 +22,12 @@ import sympy
|
|
|
22
22
|
|
|
23
23
|
import cirq
|
|
24
24
|
from cirq.transformers.analytical_decompositions.two_qubit_to_fsim import (
|
|
25
|
+
_B,
|
|
25
26
|
_decompose_two_qubit_interaction_into_two_b_gates,
|
|
26
27
|
_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops,
|
|
27
28
|
_sticky_0_to_1,
|
|
28
|
-
_B,
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
|
|
32
31
|
UNITARY_OBJS = [
|
|
33
32
|
cirq.IdentityGate(2),
|
|
34
33
|
cirq.XX**0.25,
|
|
@@ -19,11 +19,11 @@ Gate compilation methods implemented here are following the paper below:
|
|
|
19
19
|
arXiv:1603.07678
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
from typing import Iterable, List, Optional,
|
|
22
|
+
from typing import cast, Iterable, List, Optional, Tuple, TYPE_CHECKING
|
|
23
23
|
|
|
24
24
|
import numpy as np
|
|
25
25
|
|
|
26
|
-
from cirq import
|
|
26
|
+
from cirq import linalg, ops, protocols
|
|
27
27
|
from cirq.transformers.analytical_decompositions import single_qubit_decompositions, two_qubit_to_cz
|
|
28
28
|
|
|
29
29
|
if TYPE_CHECKING:
|
|
@@ -25,7 +25,7 @@ from typing import Optional, Sequence, Tuple, TYPE_CHECKING
|
|
|
25
25
|
import numpy as np
|
|
26
26
|
import sympy
|
|
27
27
|
|
|
28
|
-
from cirq import circuits,
|
|
28
|
+
from cirq import circuits, linalg, ops, protocols
|
|
29
29
|
from cirq.transformers.analytical_decompositions import single_qubit_decompositions
|
|
30
30
|
from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phxz
|
|
31
31
|
|
|
@@ -426,7 +426,7 @@ def _single_qubit_matrices_with_sqrt_iswap(
|
|
|
426
426
|
for can_decompose, decomposer in decomposers:
|
|
427
427
|
if can_decompose(kak.interaction_coefficients, weyl_tol=atol / 10):
|
|
428
428
|
return decomposer(kak, atol)
|
|
429
|
-
assert False, 'The final can_decompose should always returns True'
|
|
429
|
+
assert False, 'The final can_decompose should always returns True' # pragma: no cover
|
|
430
430
|
|
|
431
431
|
|
|
432
432
|
def _in_0_region(
|