cirq-core 1.4.1__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 +1 -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.1.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
- {cirq_core-1.4.1.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.1.dist-info/METADATA +0 -45
- {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.4.1.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
# Copyright 2024 The Cirq Developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Provides a method to do z-phase calibration for excitation-preserving gates."""
|
|
16
|
+
import multiprocessing
|
|
17
|
+
import multiprocessing.pool
|
|
18
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
|
|
19
|
+
|
|
20
|
+
import matplotlib.pyplot as plt
|
|
21
|
+
import numpy as np
|
|
22
|
+
|
|
23
|
+
from cirq import circuits, ops, protocols
|
|
24
|
+
from cirq.experiments import xeb_fitting
|
|
25
|
+
from cirq.experiments.two_qubit_xeb import parallel_xeb_workflow
|
|
26
|
+
from cirq.transformers import transformer_api
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
import pandas as pd
|
|
30
|
+
|
|
31
|
+
import cirq
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def z_phase_calibration_workflow(
|
|
35
|
+
sampler: 'cirq.Sampler',
|
|
36
|
+
qubits: Optional[Sequence['cirq.GridQubit']] = None,
|
|
37
|
+
two_qubit_gate: 'cirq.Gate' = ops.CZ,
|
|
38
|
+
options: Optional[xeb_fitting.XEBPhasedFSimCharacterizationOptions] = None,
|
|
39
|
+
n_repetitions: int = 10**4,
|
|
40
|
+
n_combinations: int = 10,
|
|
41
|
+
n_circuits: int = 20,
|
|
42
|
+
cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
|
|
43
|
+
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
|
|
44
|
+
atol: float = 1e-3,
|
|
45
|
+
num_workers_or_pool: Union[int, 'multiprocessing.pool.Pool'] = -1,
|
|
46
|
+
pairs: Optional[Sequence[Tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
|
|
47
|
+
tags: Sequence[Any] = (),
|
|
48
|
+
) -> Tuple[xeb_fitting.XEBCharacterizationResult, 'pd.DataFrame']:
|
|
49
|
+
"""Perform z-phase calibration for excitation-preserving gates.
|
|
50
|
+
|
|
51
|
+
For a given excitation-preserving two-qubit gate we assume an error model that can be described
|
|
52
|
+
using Z-rotations:
|
|
53
|
+
0: ───Rz(a)───two_qubit_gate───Rz(c)───
|
|
54
|
+
│
|
|
55
|
+
1: ───Rz(b)───two_qubit_gate───Rz(d)───
|
|
56
|
+
for some angles a, b, c, and d.
|
|
57
|
+
|
|
58
|
+
Since the two-qubit gate is a excitation-preserving-gate, it can be represented by an FSimGate
|
|
59
|
+
and the effect of rotations turns it into a PhasedFSimGate. Using XEB-data we find the
|
|
60
|
+
PhasedFSimGate parameters that minimize the infidelity of the gate.
|
|
61
|
+
|
|
62
|
+
References:
|
|
63
|
+
- https://arxiv.org/abs/2001.08343
|
|
64
|
+
- https://arxiv.org/abs/2010.07965
|
|
65
|
+
- https://arxiv.org/abs/1910.11333
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
sampler: The quantum engine or simulator to run the circuits.
|
|
69
|
+
qubits: Qubits to use. If none, use all qubits on the sampler's device.
|
|
70
|
+
two_qubit_gate: The entangling gate to use.
|
|
71
|
+
options: The XEB-fitting options. If None, calibrate only the three phase angles
|
|
72
|
+
(chi, gamma, zeta) using the representation of a two-qubit gate as an FSimGate
|
|
73
|
+
for the initial guess.
|
|
74
|
+
n_repetitions: The number of repetitions to use.
|
|
75
|
+
n_combinations: The number of combinations to generate.
|
|
76
|
+
n_circuits: The number of circuits to generate.
|
|
77
|
+
cycle_depths: The cycle depths to use.
|
|
78
|
+
random_state: The random state to use.
|
|
79
|
+
atol: Absolute tolerance to be used by the minimizer.
|
|
80
|
+
num_workers_or_pool: An optional multi-processing pool or number of workers.
|
|
81
|
+
A zero value means no multiprocessing.
|
|
82
|
+
A positive integer value will create a pool with the given number of workers.
|
|
83
|
+
A negative value will create pool with maximum number of workers.
|
|
84
|
+
pairs: Pairs to use. If not specified, use all pairs between adjacent qubits.
|
|
85
|
+
tags: Tags to add to two qubit operations.
|
|
86
|
+
Returns:
|
|
87
|
+
- An `XEBCharacterizationResult` object that contains the calibration result.
|
|
88
|
+
- A `pd.DataFrame` comparing the before and after fidelities.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
pool: Optional['multiprocessing.pool.Pool'] = None
|
|
92
|
+
local_pool = False
|
|
93
|
+
if isinstance(num_workers_or_pool, multiprocessing.pool.Pool):
|
|
94
|
+
pool = num_workers_or_pool # pragma: no cover
|
|
95
|
+
elif num_workers_or_pool != 0:
|
|
96
|
+
pool = multiprocessing.Pool(num_workers_or_pool if num_workers_or_pool > 0 else None)
|
|
97
|
+
local_pool = True
|
|
98
|
+
|
|
99
|
+
fids_df_0, circuits, sampled_df = parallel_xeb_workflow(
|
|
100
|
+
sampler=sampler,
|
|
101
|
+
qubits=qubits,
|
|
102
|
+
entangling_gate=two_qubit_gate,
|
|
103
|
+
n_repetitions=n_repetitions,
|
|
104
|
+
cycle_depths=cycle_depths,
|
|
105
|
+
n_circuits=n_circuits,
|
|
106
|
+
n_combinations=n_combinations,
|
|
107
|
+
random_state=random_state,
|
|
108
|
+
pool=pool,
|
|
109
|
+
tags=tags,
|
|
110
|
+
pairs=pairs,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if options is None:
|
|
114
|
+
options = xeb_fitting.XEBPhasedFSimCharacterizationOptions(
|
|
115
|
+
characterize_chi=True,
|
|
116
|
+
characterize_gamma=True,
|
|
117
|
+
characterize_zeta=True,
|
|
118
|
+
characterize_theta=False,
|
|
119
|
+
characterize_phi=False,
|
|
120
|
+
).with_defaults_from_gate(two_qubit_gate)
|
|
121
|
+
|
|
122
|
+
p_circuits = [
|
|
123
|
+
xeb_fitting.parameterize_circuit(circuit, options, ops.GateFamily(two_qubit_gate))
|
|
124
|
+
for circuit in circuits
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
result = xeb_fitting.characterize_phased_fsim_parameters_with_xeb_by_pair(
|
|
128
|
+
sampled_df=sampled_df,
|
|
129
|
+
parameterized_circuits=p_circuits,
|
|
130
|
+
cycle_depths=cycle_depths,
|
|
131
|
+
options=options,
|
|
132
|
+
fatol=atol,
|
|
133
|
+
xatol=atol,
|
|
134
|
+
pool=pool,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
before_after = xeb_fitting.before_and_after_characterization(
|
|
138
|
+
fids_df_0, characterization_result=result
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
if local_pool:
|
|
142
|
+
assert isinstance(pool, multiprocessing.pool.Pool)
|
|
143
|
+
pool.close()
|
|
144
|
+
return result, before_after
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def calibrate_z_phases(
|
|
148
|
+
sampler: 'cirq.Sampler',
|
|
149
|
+
qubits: Optional[Sequence['cirq.GridQubit']] = None,
|
|
150
|
+
two_qubit_gate: 'cirq.Gate' = ops.CZ,
|
|
151
|
+
options: Optional[xeb_fitting.XEBPhasedFSimCharacterizationOptions] = None,
|
|
152
|
+
n_repetitions: int = 10**4,
|
|
153
|
+
n_combinations: int = 10,
|
|
154
|
+
n_circuits: int = 20,
|
|
155
|
+
cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
|
|
156
|
+
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
|
|
157
|
+
atol: float = 1e-3,
|
|
158
|
+
num_workers_or_pool: Union[int, 'multiprocessing.pool.Pool'] = -1,
|
|
159
|
+
pairs: Optional[Sequence[Tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
|
|
160
|
+
tags: Sequence[Any] = (),
|
|
161
|
+
) -> Dict[Tuple['cirq.Qid', 'cirq.Qid'], 'cirq.PhasedFSimGate']:
|
|
162
|
+
"""Perform z-phase calibration for excitation-preserving gates.
|
|
163
|
+
|
|
164
|
+
For a given excitation-preserving two-qubit gate we assume an error model that can be described
|
|
165
|
+
using Z-rotations:
|
|
166
|
+
0: ───Rz(a)───two_qubit_gate───Rz(c)───
|
|
167
|
+
│
|
|
168
|
+
1: ───Rz(b)───two_qubit_gate───Rz(d)───
|
|
169
|
+
for some angles a, b, c, and d.
|
|
170
|
+
|
|
171
|
+
Since the two-qubit gate is a excitation-preserving gate, it can be represented by an FSimGate
|
|
172
|
+
and the effect of rotations turns it into a PhasedFSimGate. Using XEB-data we find the
|
|
173
|
+
PhasedFSimGate parameters that minimize the infidelity of the gate.
|
|
174
|
+
|
|
175
|
+
References:
|
|
176
|
+
- https://arxiv.org/abs/2001.08343
|
|
177
|
+
- https://arxiv.org/abs/2010.07965
|
|
178
|
+
- https://arxiv.org/abs/1910.11333
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
sampler: The quantum engine or simulator to run the circuits.
|
|
182
|
+
qubits: Qubits to use. If none, use all qubits on the sampler's device.
|
|
183
|
+
two_qubit_gate: The entangling gate to use.
|
|
184
|
+
options: The XEB-fitting options. If None, calibrate only the three phase angles
|
|
185
|
+
(chi, gamma, zeta) using the representation of a two-qubit gate as an FSimGate
|
|
186
|
+
for the initial guess.
|
|
187
|
+
n_repetitions: The number of repetitions to use.
|
|
188
|
+
n_combinations: The number of combinations to generate.
|
|
189
|
+
n_circuits: The number of circuits to generate.
|
|
190
|
+
cycle_depths: The cycle depths to use.
|
|
191
|
+
random_state: The random state to use.
|
|
192
|
+
atol: Absolute tolerance to be used by the minimizer.
|
|
193
|
+
num_workers_or_pool: An optional multi-processing pool or number of workers.
|
|
194
|
+
A zero value means no multiprocessing.
|
|
195
|
+
A positive integer value will create a pool with the given number of workers.
|
|
196
|
+
A negative value will create pool with maximum number of workers.
|
|
197
|
+
pairs: Pairs to use. If not specified, use all pairs between adjacent qubits.
|
|
198
|
+
tags: Tags to add to two qubit operations.
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
- A dictionary mapping qubit pairs to the calibrated PhasedFSimGates.
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
if options is None:
|
|
205
|
+
options = xeb_fitting.XEBPhasedFSimCharacterizationOptions(
|
|
206
|
+
characterize_chi=True,
|
|
207
|
+
characterize_gamma=True,
|
|
208
|
+
characterize_zeta=True,
|
|
209
|
+
characterize_theta=False,
|
|
210
|
+
characterize_phi=False,
|
|
211
|
+
).with_defaults_from_gate(two_qubit_gate)
|
|
212
|
+
|
|
213
|
+
result, _ = z_phase_calibration_workflow(
|
|
214
|
+
sampler=sampler,
|
|
215
|
+
qubits=qubits,
|
|
216
|
+
two_qubit_gate=two_qubit_gate,
|
|
217
|
+
options=options,
|
|
218
|
+
n_repetitions=n_repetitions,
|
|
219
|
+
n_combinations=n_combinations,
|
|
220
|
+
n_circuits=n_circuits,
|
|
221
|
+
cycle_depths=cycle_depths,
|
|
222
|
+
random_state=random_state,
|
|
223
|
+
atol=atol,
|
|
224
|
+
num_workers_or_pool=num_workers_or_pool,
|
|
225
|
+
tags=tags,
|
|
226
|
+
pairs=pairs,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
gates = {}
|
|
230
|
+
for pair, params in result.final_params.items():
|
|
231
|
+
params['theta'] = params.get('theta', options.theta_default or 0)
|
|
232
|
+
params['phi'] = params.get('phi', options.phi_default or 0)
|
|
233
|
+
params['zeta'] = params.get('zeta', options.zeta_default or 0)
|
|
234
|
+
params['chi'] = params.get('chi', options.chi_default or 0)
|
|
235
|
+
params['gamma'] = params.get('gamma', options.gamma_default or 0)
|
|
236
|
+
gates[pair] = ops.PhasedFSimGate(**params)
|
|
237
|
+
return gates
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def plot_z_phase_calibration_result(
|
|
241
|
+
before_after_df: 'pd.DataFrame',
|
|
242
|
+
axes: Optional[np.ndarray[Sequence[Sequence['plt.Axes']], np.dtype[np.object_]]] = None,
|
|
243
|
+
pairs: Optional[Sequence[Tuple['cirq.Qid', 'cirq.Qid']]] = None,
|
|
244
|
+
*,
|
|
245
|
+
with_error_bars: bool = False,
|
|
246
|
+
) -> np.ndarray[Sequence[Sequence['plt.Axes']], np.dtype[np.object_]]:
|
|
247
|
+
"""A helper method to plot the result of running z-phase calibration.
|
|
248
|
+
|
|
249
|
+
Note that the plotted fidelity is a statistical estimate of the true fidelity and as a result
|
|
250
|
+
may be outside the [0, 1] range.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
before_after_df: The second return object of running `z_phase_calibration_workflow`.
|
|
254
|
+
axes: And ndarray of the axes to plot on.
|
|
255
|
+
The number of axes is expected to be >= number of qubit pairs.
|
|
256
|
+
pairs: If provided, only the given pairs are plotted.
|
|
257
|
+
with_error_bars: Whether to add error bars or not.
|
|
258
|
+
The width of the bar is an upper bound on standard variation of the estimated fidelity.
|
|
259
|
+
"""
|
|
260
|
+
if pairs is None:
|
|
261
|
+
pairs = before_after_df.index
|
|
262
|
+
if axes is None:
|
|
263
|
+
# Create a 16x9 rectangle.
|
|
264
|
+
ncols = int(np.ceil(np.sqrt(9 / 16 * len(pairs))))
|
|
265
|
+
nrows = (len(pairs) + ncols - 1) // ncols
|
|
266
|
+
_, axes = plt.subplots(nrows=nrows, ncols=ncols)
|
|
267
|
+
axes = axes if isinstance(axes, np.ndarray) else np.array(axes)
|
|
268
|
+
for pair, ax in zip(pairs, axes.flatten()):
|
|
269
|
+
row = before_after_df.loc[[pair]].iloc[0]
|
|
270
|
+
ax.errorbar(
|
|
271
|
+
row.cycle_depths_0,
|
|
272
|
+
row.fidelities_0,
|
|
273
|
+
yerr=row.layer_fid_std_0 * with_error_bars,
|
|
274
|
+
label='original',
|
|
275
|
+
)
|
|
276
|
+
ax.errorbar(
|
|
277
|
+
row.cycle_depths_0,
|
|
278
|
+
row.fidelities_c,
|
|
279
|
+
yerr=row.layer_fid_std_c * with_error_bars,
|
|
280
|
+
label='calibrated',
|
|
281
|
+
)
|
|
282
|
+
ax.axhline(1, linestyle='--')
|
|
283
|
+
ax.set_xlabel('cycle depth')
|
|
284
|
+
ax.set_ylabel('fidelity estimate')
|
|
285
|
+
ax.set_title('-'.join(str(q) for q in pair))
|
|
286
|
+
ax.legend()
|
|
287
|
+
return axes
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def _z_angles(old: ops.PhasedFSimGate, new: ops.PhasedFSimGate) -> Tuple[float, float, float]:
|
|
291
|
+
"""Computes a set of possible 3 z-phases that result in the change in gamma, zeta, and chi."""
|
|
292
|
+
# This procedure is the inverse of PhasedFSimGate.from_fsim_rz
|
|
293
|
+
delta_gamma = new.gamma - old.gamma
|
|
294
|
+
delta_zeta = new.zeta - old.zeta
|
|
295
|
+
delta_chi = new.chi - old.chi
|
|
296
|
+
return (-delta_gamma + delta_chi, -delta_gamma - delta_zeta, delta_zeta - delta_chi)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@transformer_api.transformer
|
|
300
|
+
class CalibrationTransformer:
|
|
301
|
+
|
|
302
|
+
def __init__(
|
|
303
|
+
self,
|
|
304
|
+
target: 'cirq.Gate',
|
|
305
|
+
calibration_map: Dict[Tuple['cirq.Qid', 'cirq.Qid'], 'cirq.PhasedFSimGate'],
|
|
306
|
+
):
|
|
307
|
+
"""Create a CalibrationTransformer.
|
|
308
|
+
|
|
309
|
+
The transformer adds 3 ZPowGates around each calibrated gate to cancel the
|
|
310
|
+
effect of z-phases.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
target: The target gate. Any gate matching this
|
|
314
|
+
will be replaced based on the content of `calibration_map`.
|
|
315
|
+
calibration_map:
|
|
316
|
+
A map mapping qubit pairs to calibrated gates. This is the output of
|
|
317
|
+
calling `calibrate_z_phases`.
|
|
318
|
+
"""
|
|
319
|
+
self.target = target
|
|
320
|
+
if isinstance(target, ops.PhasedFSimGate):
|
|
321
|
+
self.target_as_fsim = target
|
|
322
|
+
elif (gate := ops.PhasedFSimGate.from_matrix(protocols.unitary(target))) is not None:
|
|
323
|
+
self.target_as_fsim = gate
|
|
324
|
+
else:
|
|
325
|
+
raise ValueError(f"{target} is not equivalent to a PhasedFSimGate")
|
|
326
|
+
self.calibration_map = calibration_map
|
|
327
|
+
|
|
328
|
+
def __call__(
|
|
329
|
+
self,
|
|
330
|
+
circuit: 'cirq.AbstractCircuit',
|
|
331
|
+
*,
|
|
332
|
+
context: Optional[transformer_api.TransformerContext] = None,
|
|
333
|
+
) -> 'cirq.Circuit':
|
|
334
|
+
"""Adds 3 ZPowGates around each calibrated gate to cancel the effect of Z phases.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
circuit: Circuit to transform.
|
|
338
|
+
context: Optional transformer context (not used).
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
New circuit with the extra ZPowGates.
|
|
342
|
+
"""
|
|
343
|
+
new_moments: List[Union[List[cirq.Operation], 'cirq.Moment']] = []
|
|
344
|
+
for moment in circuit:
|
|
345
|
+
before = []
|
|
346
|
+
after = []
|
|
347
|
+
for op in moment:
|
|
348
|
+
if op.gate != self.target:
|
|
349
|
+
# not a target.
|
|
350
|
+
continue
|
|
351
|
+
assert len(op.qubits) == 2
|
|
352
|
+
gate = self.calibration_map.get(op.qubits, None) or self.calibration_map.get(
|
|
353
|
+
op.qubits[::-1], None
|
|
354
|
+
)
|
|
355
|
+
if gate is None:
|
|
356
|
+
# no calibration available.
|
|
357
|
+
continue
|
|
358
|
+
angles = np.array(_z_angles(self.target_as_fsim, gate)) / np.pi
|
|
359
|
+
angles = -angles # Take the negative to cancel the effect.
|
|
360
|
+
before.append(ops.Z(op.qubits[0]) ** angles[0])
|
|
361
|
+
before.append(ops.Z(op.qubits[1]) ** angles[1])
|
|
362
|
+
after.append(ops.Z(op.qubits[0]) ** angles[2])
|
|
363
|
+
if before:
|
|
364
|
+
new_moments.append(before)
|
|
365
|
+
new_moments.append(moment)
|
|
366
|
+
if after:
|
|
367
|
+
new_moments.append(after)
|
|
368
|
+
return circuits.Circuit.from_moments(*new_moments)
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Copyright 2024 The Cirq Developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
import pandas as pd
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
19
|
+
import cirq
|
|
20
|
+
from cirq.experiments.xeb_fitting import XEBPhasedFSimCharacterizationOptions
|
|
21
|
+
from cirq.experiments.z_phase_calibration import (
|
|
22
|
+
calibrate_z_phases,
|
|
23
|
+
CalibrationTransformer,
|
|
24
|
+
plot_z_phase_calibration_result,
|
|
25
|
+
z_phase_calibration_workflow,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
_ANGLES = ['theta', 'phi', 'chi', 'zeta', 'gamma']
|
|
29
|
+
# fix random generator seed to ensure reproducibility and faster convergence
|
|
30
|
+
_SEED = 276154030
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _create_tests(n, with_options: bool = False):
|
|
34
|
+
rng = np.random.default_rng(_SEED)
|
|
35
|
+
angles = (rng.random((n, 5)) * 2 - 1) * np.pi
|
|
36
|
+
# Add errors to the last 3 angles (chi, zeta, gamma).
|
|
37
|
+
# The errors are in the union (-2, -1) U (1, 2).
|
|
38
|
+
# This is because we run the tests with few repetitions so a small error might not get fixed.
|
|
39
|
+
error = np.concatenate(
|
|
40
|
+
[np.zeros((n, 2)), (rng.random((n, 3)) + 1) * rng.choice([-1, 1], (n, 3))], axis=-1
|
|
41
|
+
)
|
|
42
|
+
if with_options:
|
|
43
|
+
options = []
|
|
44
|
+
for _ in range(n):
|
|
45
|
+
v = [False, False, False]
|
|
46
|
+
# Calibrate only one to keep the run time down.
|
|
47
|
+
v[rng.integers(0, 3)] = True
|
|
48
|
+
options.append(
|
|
49
|
+
{
|
|
50
|
+
'characterize_chi': v[0],
|
|
51
|
+
'characterize_gamma': v[1],
|
|
52
|
+
'characterize_zeta': v[2],
|
|
53
|
+
'characterize_phi': False,
|
|
54
|
+
'characterize_theta': False,
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return zip(angles, error, options)
|
|
59
|
+
return zip(angles, error)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _trace_distance(A, B):
|
|
63
|
+
return 0.5 * np.abs(np.linalg.eigvals(A - B)).sum()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class _TestSimulator(cirq.Simulator):
|
|
67
|
+
"""A simulator that replaces a specific gate by another."""
|
|
68
|
+
|
|
69
|
+
def __init__(self, gate: cirq.Gate, replacement: cirq.Gate, **kwargs):
|
|
70
|
+
super().__init__(**kwargs)
|
|
71
|
+
self.gate = gate
|
|
72
|
+
self.replacement = replacement
|
|
73
|
+
|
|
74
|
+
def _core_iterator(
|
|
75
|
+
self,
|
|
76
|
+
circuit: 'cirq.AbstractCircuit',
|
|
77
|
+
sim_state,
|
|
78
|
+
all_measurements_are_terminal: bool = False,
|
|
79
|
+
):
|
|
80
|
+
new_circuit = cirq.Circuit(
|
|
81
|
+
[
|
|
82
|
+
[op if op.gate != self.gate else self.replacement(*op.qubits) for op in m]
|
|
83
|
+
for m in circuit
|
|
84
|
+
]
|
|
85
|
+
)
|
|
86
|
+
yield from super()._core_iterator(new_circuit, sim_state, all_measurements_are_terminal)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@pytest.mark.parametrize(
|
|
90
|
+
['angles', 'error', 'characterization_flags'], _create_tests(n=10, with_options=True)
|
|
91
|
+
)
|
|
92
|
+
def test_calibrate_z_phases(angles, error, characterization_flags):
|
|
93
|
+
|
|
94
|
+
original_gate = cirq.PhasedFSimGate(**{k: v for k, v in zip(_ANGLES, angles)})
|
|
95
|
+
actual_gate = cirq.PhasedFSimGate(**{k: v + e for k, v, e in zip(_ANGLES, angles, error)})
|
|
96
|
+
|
|
97
|
+
options = XEBPhasedFSimCharacterizationOptions(
|
|
98
|
+
**{f'{n}_default': t for n, t in zip(_ANGLES, angles)}, **characterization_flags
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
sampler = _TestSimulator(original_gate, actual_gate, seed=_SEED)
|
|
102
|
+
qubits = cirq.q(0, 0), cirq.q(0, 1)
|
|
103
|
+
calibrated_gate = calibrate_z_phases(
|
|
104
|
+
sampler,
|
|
105
|
+
qubits,
|
|
106
|
+
original_gate,
|
|
107
|
+
options,
|
|
108
|
+
n_repetitions=10,
|
|
109
|
+
n_combinations=10,
|
|
110
|
+
n_circuits=10,
|
|
111
|
+
cycle_depths=range(3, 10),
|
|
112
|
+
random_state=_SEED,
|
|
113
|
+
)[qubits]
|
|
114
|
+
|
|
115
|
+
initial_unitary = cirq.unitary(original_gate)
|
|
116
|
+
final_unitary = cirq.unitary(calibrated_gate)
|
|
117
|
+
target_unitary = cirq.unitary(actual_gate)
|
|
118
|
+
maximally_mixed_state = np.eye(4) / 2
|
|
119
|
+
dm_initial = initial_unitary @ maximally_mixed_state @ initial_unitary.T.conj()
|
|
120
|
+
dm_final = final_unitary @ maximally_mixed_state @ final_unitary.T.conj()
|
|
121
|
+
dm_target = target_unitary @ maximally_mixed_state @ target_unitary.T.conj()
|
|
122
|
+
|
|
123
|
+
original_dist = _trace_distance(dm_initial, dm_target)
|
|
124
|
+
new_dist = _trace_distance(dm_final, dm_target)
|
|
125
|
+
|
|
126
|
+
# Either we reduced the error or the error is small enough.
|
|
127
|
+
assert new_dist < original_dist or new_dist < 1e-6
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@pytest.mark.parametrize(['angles', 'error'], _create_tests(n=3))
|
|
131
|
+
def test_calibrate_z_phases_no_options(angles, error):
|
|
132
|
+
|
|
133
|
+
original_gate = cirq.PhasedFSimGate(**{k: v for k, v in zip(_ANGLES, angles)})
|
|
134
|
+
actual_gate = cirq.PhasedFSimGate(**{k: v + e for k, v, e in zip(_ANGLES, angles, error)})
|
|
135
|
+
|
|
136
|
+
sampler = _TestSimulator(original_gate, actual_gate, seed=_SEED)
|
|
137
|
+
qubits = cirq.q(0, 0), cirq.q(0, 1)
|
|
138
|
+
calibrated_gate = calibrate_z_phases(
|
|
139
|
+
sampler,
|
|
140
|
+
qubits,
|
|
141
|
+
original_gate,
|
|
142
|
+
options=None,
|
|
143
|
+
n_repetitions=10,
|
|
144
|
+
n_combinations=10,
|
|
145
|
+
n_circuits=10,
|
|
146
|
+
cycle_depths=range(3, 10),
|
|
147
|
+
random_state=_SEED,
|
|
148
|
+
)[qubits]
|
|
149
|
+
|
|
150
|
+
initial_unitary = cirq.unitary(original_gate)
|
|
151
|
+
final_unitary = cirq.unitary(calibrated_gate)
|
|
152
|
+
target_unitary = cirq.unitary(actual_gate)
|
|
153
|
+
maximally_mixed_state = np.eye(4) / 2
|
|
154
|
+
dm_initial = initial_unitary @ maximally_mixed_state @ initial_unitary.T.conj()
|
|
155
|
+
dm_final = final_unitary @ maximally_mixed_state @ final_unitary.T.conj()
|
|
156
|
+
dm_target = target_unitary @ maximally_mixed_state @ target_unitary.T.conj()
|
|
157
|
+
|
|
158
|
+
original_dist = _trace_distance(dm_initial, dm_target)
|
|
159
|
+
new_dist = _trace_distance(dm_final, dm_target)
|
|
160
|
+
|
|
161
|
+
# Either we reduced the error or the error is small enough.
|
|
162
|
+
assert new_dist < original_dist or new_dist < 1e-6
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@pytest.mark.parametrize(['angles', 'error'], _create_tests(n=3))
|
|
166
|
+
def test_calibrate_z_phases_workflow_no_options(angles, error):
|
|
167
|
+
|
|
168
|
+
original_gate = cirq.PhasedFSimGate(**{k: v for k, v in zip(_ANGLES, angles)})
|
|
169
|
+
actual_gate = cirq.PhasedFSimGate(**{k: v + e for k, v, e in zip(_ANGLES, angles, error)})
|
|
170
|
+
|
|
171
|
+
sampler = _TestSimulator(original_gate, actual_gate, seed=_SEED)
|
|
172
|
+
qubits = cirq.q(0, 0), cirq.q(0, 1)
|
|
173
|
+
result, _ = z_phase_calibration_workflow(
|
|
174
|
+
sampler,
|
|
175
|
+
qubits,
|
|
176
|
+
original_gate,
|
|
177
|
+
options=None,
|
|
178
|
+
n_repetitions=1,
|
|
179
|
+
n_combinations=1,
|
|
180
|
+
n_circuits=1,
|
|
181
|
+
cycle_depths=(1, 2),
|
|
182
|
+
random_state=_SEED,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
for params in result.final_params.values():
|
|
186
|
+
assert 'zeta' in params
|
|
187
|
+
assert 'chi' in params
|
|
188
|
+
assert 'gamma' in params
|
|
189
|
+
assert 'phi' not in params
|
|
190
|
+
assert 'theta' not in params
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def test_plot_z_phase_calibration_result():
|
|
194
|
+
df = pd.DataFrame()
|
|
195
|
+
qs = cirq.q(0, 0), cirq.q(0, 1), cirq.q(0, 2)
|
|
196
|
+
df.index = [qs[:2], qs[-2:]]
|
|
197
|
+
df['cycle_depths_0'] = [[1, 2, 3]] * 2
|
|
198
|
+
df['fidelities_0'] = [[0.9, 0.8, 0.7], [0.6, 0.4, 0.1]]
|
|
199
|
+
df['layer_fid_std_0'] = [0.1, 0.2]
|
|
200
|
+
df['fidelities_c'] = [[0.9, 0.92, 0.93], [0.7, 0.77, 0.8]]
|
|
201
|
+
df['layer_fid_std_c'] = [0.2, 0.3]
|
|
202
|
+
|
|
203
|
+
axes = plot_z_phase_calibration_result(before_after_df=df)
|
|
204
|
+
|
|
205
|
+
np.testing.assert_allclose(axes[0].lines[0].get_xdata().astype(float), [1, 2, 3])
|
|
206
|
+
np.testing.assert_allclose(axes[0].lines[0].get_ydata().astype(float), [0.9, 0.8, 0.7])
|
|
207
|
+
np.testing.assert_allclose(axes[0].lines[1].get_ydata().astype(float), [0.9, 0.92, 0.93])
|
|
208
|
+
|
|
209
|
+
np.testing.assert_allclose(axes[1].lines[0].get_xdata().astype(float), [1, 2, 3])
|
|
210
|
+
np.testing.assert_allclose(axes[1].lines[0].get_ydata().astype(float), [0.6, 0.4, 0.1])
|
|
211
|
+
np.testing.assert_allclose(axes[1].lines[1].get_ydata().astype(float), [0.7, 0.77, 0.8])
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@pytest.mark.parametrize('angles', 2 * np.pi * np.random.random((10, 10)))
|
|
215
|
+
def test_transform_circuit(angles):
|
|
216
|
+
theta, phi = angles[:2]
|
|
217
|
+
old_zs = angles[2:6]
|
|
218
|
+
new_zs = angles[6:]
|
|
219
|
+
gate = cirq.PhasedFSimGate.from_fsim_rz(theta, phi, old_zs[:2], old_zs[2:])
|
|
220
|
+
fsim = cirq.PhasedFSimGate.from_fsim_rz(theta, phi, new_zs[:2], new_zs[2:])
|
|
221
|
+
c = cirq.Circuit(gate(cirq.q(0), cirq.q(1)))
|
|
222
|
+
replacement_map = {(cirq.q(1), cirq.q(0)): fsim}
|
|
223
|
+
|
|
224
|
+
new_circuit = CalibrationTransformer(gate, replacement_map)(c)
|
|
225
|
+
|
|
226
|
+
# we replace the old gate with the `fsim` gate the result should be that the overall
|
|
227
|
+
# unitary equals the unitary of the original (ideal) gate.
|
|
228
|
+
circuit_with_replacement_gate = cirq.Circuit(
|
|
229
|
+
op if op.gate != gate else fsim(*op.qubits) for op in new_circuit.all_operations()
|
|
230
|
+
)
|
|
231
|
+
np.testing.assert_allclose(cirq.unitary(circuit_with_replacement_gate), cirq.unitary(c))
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def test_transform_circuit_invalid_gate_raises():
|
|
235
|
+
with pytest.raises(ValueError, match="is not equivalent to a PhasedFSimGate"):
|
|
236
|
+
_ = CalibrationTransformer(cirq.XX, {})
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def test_transform_circuit_uncalibrated_gates_pass():
|
|
240
|
+
c = cirq.Circuit(cirq.CZ(cirq.q(0), cirq.q(1)), cirq.measure(cirq.q(0)))
|
|
241
|
+
assert c == CalibrationTransformer(cirq.CZ, {})(c)
|
cirq/interop/__init__.py
CHANGED
|
@@ -13,4 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""Methods for interoperating with other quantum software."""
|
|
15
15
|
|
|
16
|
-
from cirq.interop.quirk import
|
|
16
|
+
from cirq.interop.quirk import (
|
|
17
|
+
quirk_json_to_circuit as quirk_json_to_circuit,
|
|
18
|
+
quirk_url_to_circuit as quirk_url_to_circuit,
|
|
19
|
+
)
|
cirq/interop/quirk/__init__.py
CHANGED
|
@@ -20,9 +20,12 @@ References:
|
|
|
20
20
|
|
|
21
21
|
# Imports from cells are only to ensure operation reprs work correctly.
|
|
22
22
|
from cirq.interop.quirk.cells import (
|
|
23
|
-
QuirkArithmeticGate,
|
|
24
|
-
QuirkInputRotationOperation,
|
|
25
|
-
QuirkQubitPermutationGate,
|
|
23
|
+
QuirkArithmeticGate as QuirkArithmeticGate,
|
|
24
|
+
QuirkInputRotationOperation as QuirkInputRotationOperation,
|
|
25
|
+
QuirkQubitPermutationGate as QuirkQubitPermutationGate,
|
|
26
26
|
)
|
|
27
27
|
|
|
28
|
-
from cirq.interop.quirk.url_to_circuit import
|
|
28
|
+
from cirq.interop.quirk.url_to_circuit import (
|
|
29
|
+
quirk_json_to_circuit as quirk_json_to_circuit,
|
|
30
|
+
quirk_url_to_circuit as quirk_url_to_circuit,
|
|
31
|
+
)
|
|
@@ -13,17 +13,28 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""This module defines building blocks for parsing Quirk circuits."""
|
|
15
15
|
|
|
16
|
-
from cirq.interop.quirk.cells.all_cells import
|
|
16
|
+
from cirq.interop.quirk.cells.all_cells import (
|
|
17
|
+
generate_all_quirk_cell_makers as generate_all_quirk_cell_makers,
|
|
18
|
+
)
|
|
17
19
|
|
|
18
|
-
from cirq.interop.quirk.cells.cell import
|
|
20
|
+
from cirq.interop.quirk.cells.cell import (
|
|
21
|
+
Cell as Cell,
|
|
22
|
+
CellMaker as CellMaker,
|
|
23
|
+
CellMakerArgs as CellMakerArgs,
|
|
24
|
+
ExplicitOperationsCell as ExplicitOperationsCell,
|
|
25
|
+
)
|
|
19
26
|
|
|
20
|
-
from cirq.interop.quirk.cells.composite_cell import CompositeCell
|
|
27
|
+
from cirq.interop.quirk.cells.composite_cell import CompositeCell as CompositeCell
|
|
21
28
|
|
|
22
|
-
from cirq.interop.quirk.cells.qubit_permutation_cells import
|
|
29
|
+
from cirq.interop.quirk.cells.qubit_permutation_cells import (
|
|
30
|
+
QuirkQubitPermutationGate as QuirkQubitPermutationGate,
|
|
31
|
+
)
|
|
23
32
|
|
|
24
|
-
from cirq.interop.quirk.cells.arithmetic_cells import QuirkArithmeticGate
|
|
33
|
+
from cirq.interop.quirk.cells.arithmetic_cells import QuirkArithmeticGate as QuirkArithmeticGate
|
|
25
34
|
|
|
26
|
-
from cirq.interop.quirk.cells.input_rotation_cells import
|
|
35
|
+
from cirq.interop.quirk.cells.input_rotation_cells import (
|
|
36
|
+
QuirkInputRotationOperation as QuirkInputRotationOperation,
|
|
37
|
+
)
|
|
27
38
|
|
|
28
39
|
import cirq.interop.quirk.cells.swap_cell
|
|
29
40
|
import cirq.interop.quirk.cells.control_cells
|