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
|
@@ -11,16 +11,15 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
from typing import List, Optional, Set
|
|
15
16
|
|
|
16
17
|
import pytest
|
|
18
|
+
|
|
17
19
|
import cirq
|
|
18
|
-
from cirq import
|
|
20
|
+
from cirq import Operation, PointOptimizationSummary, PointOptimizer
|
|
19
21
|
from cirq.testing import EqualsTester
|
|
20
22
|
|
|
21
|
-
if TYPE_CHECKING:
|
|
22
|
-
import cirq
|
|
23
|
-
|
|
24
23
|
|
|
25
24
|
def test_equality():
|
|
26
25
|
a = cirq.NamedQubit('a')
|
|
@@ -62,8 +61,8 @@ class ReplaceWithXGates(PointOptimizer):
|
|
|
62
61
|
"""
|
|
63
62
|
|
|
64
63
|
def optimization_at(
|
|
65
|
-
self, circuit:
|
|
66
|
-
) -> Optional[
|
|
64
|
+
self, circuit: cirq.Circuit, index: int, op: cirq.Operation
|
|
65
|
+
) -> Optional[cirq.PointOptimizationSummary]:
|
|
67
66
|
end = index + 1
|
|
68
67
|
new_ops = [cirq.X(q) for q in op.qubits]
|
|
69
68
|
done = False
|
|
@@ -156,8 +155,8 @@ def test_point_optimizer_raises_on_gates_changing_qubits():
|
|
|
156
155
|
"""Changes all single qubit operations to act on LineQubit(42)"""
|
|
157
156
|
|
|
158
157
|
def optimization_at(
|
|
159
|
-
self, circuit:
|
|
160
|
-
) -> Optional[
|
|
158
|
+
self, circuit: cirq.Circuit, index: int, op: cirq.Operation
|
|
159
|
+
) -> Optional[cirq.PointOptimizationSummary]:
|
|
161
160
|
new_op = op
|
|
162
161
|
if len(op.qubits) == 1 and isinstance(op, cirq.GateOperation):
|
|
163
162
|
new_op = op.gate(cirq.LineQubit(42))
|
cirq/circuits/qasm_output.py
CHANGED
|
@@ -14,12 +14,14 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility classes for representing QASM."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import re
|
|
20
|
+
from typing import Callable, Dict, Iterator, Optional, Sequence, Tuple, TYPE_CHECKING, Union
|
|
21
|
+
|
|
20
22
|
import numpy as np
|
|
21
23
|
|
|
22
|
-
from cirq import
|
|
24
|
+
from cirq import linalg, ops, protocols, value
|
|
23
25
|
|
|
24
26
|
if TYPE_CHECKING:
|
|
25
27
|
import cirq
|
|
@@ -46,15 +48,15 @@ class QasmUGate(ops.Gate):
|
|
|
46
48
|
return 1
|
|
47
49
|
|
|
48
50
|
@staticmethod
|
|
49
|
-
def from_matrix(mat: np.ndarray) ->
|
|
51
|
+
def from_matrix(mat: np.ndarray) -> QasmUGate:
|
|
50
52
|
pre_phase, rotation, post_phase = linalg.deconstruct_single_qubit_matrix_into_angles(mat)
|
|
51
53
|
return QasmUGate(rotation / np.pi, post_phase / np.pi, pre_phase / np.pi)
|
|
52
54
|
|
|
53
55
|
def _has_unitary_(self):
|
|
54
56
|
return True
|
|
55
57
|
|
|
56
|
-
def _qasm_(self, qubits: Tuple[
|
|
57
|
-
args.validate_version('2.0')
|
|
58
|
+
def _qasm_(self, qubits: Tuple[cirq.Qid, ...], args: cirq.QasmArgs) -> str:
|
|
59
|
+
args.validate_version('2.0', '3.0')
|
|
58
60
|
return args.format(
|
|
59
61
|
'u3({0:half_turns},{1:half_turns},{2:half_turns}) {3};\n',
|
|
60
62
|
self.theta,
|
|
@@ -86,13 +88,13 @@ class QasmUGate(ops.Gate):
|
|
|
86
88
|
return {'theta': self.theta, 'phi': self.phi, 'lmda': self.lmda}
|
|
87
89
|
|
|
88
90
|
@classmethod
|
|
89
|
-
def _from_json_dict_(cls, theta: float, phi: float, lmda: float, **kwargs) ->
|
|
91
|
+
def _from_json_dict_(cls, theta: float, phi: float, lmda: float, **kwargs) -> QasmUGate:
|
|
90
92
|
return cls(theta, phi, lmda)
|
|
91
93
|
|
|
92
94
|
|
|
93
95
|
@value.value_equality
|
|
94
96
|
class QasmTwoQubitGate(ops.Gate):
|
|
95
|
-
def __init__(self, kak:
|
|
97
|
+
def __init__(self, kak: cirq.KakDecomposition) -> None:
|
|
96
98
|
"""A two qubit gate represented in QASM by the KAK decomposition.
|
|
97
99
|
|
|
98
100
|
All angles are in half turns. Assumes a canonicalized KAK
|
|
@@ -110,7 +112,7 @@ class QasmTwoQubitGate(ops.Gate):
|
|
|
110
112
|
return self.kak
|
|
111
113
|
|
|
112
114
|
@staticmethod
|
|
113
|
-
def from_matrix(mat: np.ndarray, atol=1e-8) ->
|
|
115
|
+
def from_matrix(mat: np.ndarray, atol=1e-8) -> QasmTwoQubitGate:
|
|
114
116
|
"""Creates a QasmTwoQubitGate from the given matrix.
|
|
115
117
|
|
|
116
118
|
Args:
|
|
@@ -126,7 +128,7 @@ class QasmTwoQubitGate(ops.Gate):
|
|
|
126
128
|
def _unitary_(self):
|
|
127
129
|
return protocols.unitary(self.kak)
|
|
128
130
|
|
|
129
|
-
def _decompose_(self, qubits: Sequence[
|
|
131
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
130
132
|
q0, q1 = qubits
|
|
131
133
|
x, y, z = self.kak.interaction_coefficients
|
|
132
134
|
a = x * -2 / np.pi + 0.5
|
|
@@ -170,8 +172,8 @@ class QasmOutput:
|
|
|
170
172
|
|
|
171
173
|
def __init__(
|
|
172
174
|
self,
|
|
173
|
-
operations:
|
|
174
|
-
qubits: Tuple[
|
|
175
|
+
operations: cirq.OP_TREE,
|
|
176
|
+
qubits: Tuple[cirq.Qid, ...],
|
|
175
177
|
header: str = '',
|
|
176
178
|
precision: int = 10,
|
|
177
179
|
version: str = '2.0',
|
|
@@ -197,11 +199,13 @@ class QasmOutput:
|
|
|
197
199
|
meas_key_id_map, meas_comments = self._generate_measurement_ids()
|
|
198
200
|
self.meas_comments = meas_comments
|
|
199
201
|
qubit_id_map = self._generate_qubit_ids()
|
|
202
|
+
self.cregs = self._generate_cregs(meas_key_id_map)
|
|
200
203
|
self.args = protocols.QasmArgs(
|
|
201
204
|
precision=precision,
|
|
202
205
|
version=version,
|
|
203
206
|
qubit_id_map=qubit_id_map,
|
|
204
207
|
meas_key_id_map=meas_key_id_map,
|
|
208
|
+
meas_key_bitcount={k: v[0] for k, v in self.cregs.items()},
|
|
205
209
|
)
|
|
206
210
|
|
|
207
211
|
def _generate_measurement_ids(self) -> Tuple[Dict[str, str], Dict[str, Optional[str]]]:
|
|
@@ -223,9 +227,33 @@ class QasmOutput:
|
|
|
223
227
|
meas_key_id_map[key] = meas_id
|
|
224
228
|
return meas_key_id_map, meas_comments
|
|
225
229
|
|
|
226
|
-
def _generate_qubit_ids(self) -> Dict[
|
|
230
|
+
def _generate_qubit_ids(self) -> Dict[cirq.Qid, str]:
|
|
227
231
|
return {qubit: f'q[{i}]' for i, qubit in enumerate(self.qubits)}
|
|
228
232
|
|
|
233
|
+
def _generate_cregs(self, meas_key_id_map: Dict[str, str]) -> Dict[str, tuple[int, str]]:
|
|
234
|
+
"""Pick an id for the creg that will store each measurement
|
|
235
|
+
|
|
236
|
+
This function finds the largest measurement using each key.
|
|
237
|
+
That is, if multiple measurements are made with the same key,
|
|
238
|
+
it will use the key with the most number of qubits.
|
|
239
|
+
|
|
240
|
+
Returns: dictionary with key of measurement id and value of (#qubits, comment).
|
|
241
|
+
"""
|
|
242
|
+
cregs: Dict[str, tuple[int, str]] = {}
|
|
243
|
+
for meas in self.measurements:
|
|
244
|
+
key = protocols.measurement_key_name(meas)
|
|
245
|
+
meas_id = meas_key_id_map[key]
|
|
246
|
+
|
|
247
|
+
if self.meas_comments[key] is not None:
|
|
248
|
+
comment = f' // Measurement: {self.meas_comments[key]}'
|
|
249
|
+
else:
|
|
250
|
+
comment = ''
|
|
251
|
+
|
|
252
|
+
if meas_id not in cregs or cregs[meas_id][0] < len(meas.qubits):
|
|
253
|
+
cregs[meas_id] = (len(meas.qubits), comment)
|
|
254
|
+
|
|
255
|
+
return cregs
|
|
256
|
+
|
|
229
257
|
def is_valid_qasm_id(self, id_str: str) -> bool:
|
|
230
258
|
"""Test if id_str is a valid id in QASM grammar."""
|
|
231
259
|
return self.valid_id_re.match(id_str) is not None
|
|
@@ -246,7 +274,7 @@ class QasmOutput:
|
|
|
246
274
|
return ''.join(output)
|
|
247
275
|
|
|
248
276
|
def _write_qasm(self, output_func: Callable[[str], None]) -> None:
|
|
249
|
-
self.args.validate_version('2.0')
|
|
277
|
+
self.args.validate_version('2.0', '3.0')
|
|
250
278
|
|
|
251
279
|
# Generate nice line spacing
|
|
252
280
|
line_gap = [0]
|
|
@@ -267,8 +295,12 @@ class QasmOutput:
|
|
|
267
295
|
output('\n')
|
|
268
296
|
|
|
269
297
|
# Version
|
|
270
|
-
output('OPENQASM
|
|
271
|
-
|
|
298
|
+
output(f'OPENQASM {self.args.version};\n')
|
|
299
|
+
if self.args.version == '2.0':
|
|
300
|
+
output('include "qelib1.inc";\n')
|
|
301
|
+
else:
|
|
302
|
+
output('include "stdgates.inc";\n')
|
|
303
|
+
|
|
272
304
|
output_line_gap(2)
|
|
273
305
|
|
|
274
306
|
# Function definitions
|
|
@@ -276,23 +308,22 @@ class QasmOutput:
|
|
|
276
308
|
|
|
277
309
|
# Register definitions
|
|
278
310
|
# Qubit registers
|
|
311
|
+
|
|
279
312
|
output(f"// Qubits: [{', '.join(map(str, self.qubits))}]\n")
|
|
280
313
|
if len(self.qubits) > 0:
|
|
281
|
-
|
|
314
|
+
if self.args.version == '2.0':
|
|
315
|
+
output(f'qreg q[{len(self.qubits)}];\n')
|
|
316
|
+
else:
|
|
317
|
+
output(f'qubit[{len(self.qubits)}] q;\n')
|
|
318
|
+
|
|
282
319
|
# Classical registers
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if key in already_output_keys:
|
|
288
|
-
continue
|
|
289
|
-
already_output_keys.add(key)
|
|
290
|
-
meas_id = self.args.meas_key_id_map[key]
|
|
291
|
-
comment = self.meas_comments[key]
|
|
292
|
-
if comment is None:
|
|
293
|
-
output(f'creg {meas_id}[{len(meas.qubits)}];\n')
|
|
320
|
+
for meas_id in self.cregs:
|
|
321
|
+
length, comment = self.cregs[meas_id]
|
|
322
|
+
if self.args.version == '2.0':
|
|
323
|
+
output(f'creg {meas_id}[{length}];{comment}\n')
|
|
294
324
|
else:
|
|
295
|
-
output(f'
|
|
325
|
+
output(f'bit[{length}] {meas_id};{comment}\n')
|
|
326
|
+
|
|
296
327
|
# In OpenQASM 2.0, the transformation of global phase gates is ignored.
|
|
297
328
|
# Therefore, no newline is created when the operations contained in
|
|
298
329
|
# a circuit consist only of global phase gates.
|
|
@@ -304,11 +335,11 @@ class QasmOutput:
|
|
|
304
335
|
|
|
305
336
|
def _write_operations(
|
|
306
337
|
self,
|
|
307
|
-
op_tree:
|
|
338
|
+
op_tree: cirq.OP_TREE,
|
|
308
339
|
output: Callable[[str], None],
|
|
309
340
|
output_line_gap: Callable[[int], None],
|
|
310
341
|
) -> None:
|
|
311
|
-
def keep(op:
|
|
342
|
+
def keep(op: cirq.Operation) -> bool:
|
|
312
343
|
return protocols.qasm(op, args=self.args, default=None) is not None
|
|
313
344
|
|
|
314
345
|
def fallback(op):
|
|
@@ -320,7 +351,7 @@ class QasmOutput:
|
|
|
320
351
|
return NotImplemented
|
|
321
352
|
|
|
322
353
|
if len(op.qubits) == 1:
|
|
323
|
-
return QasmUGate.from_matrix(mat).on(*op.qubits)
|
|
354
|
+
return QasmUGate.from_matrix(mat).on(*op.qubits) # pragma: no cover
|
|
324
355
|
return QasmTwoQubitGate.from_matrix(mat).on(*op.qubits)
|
|
325
356
|
|
|
326
357
|
def on_stuck(bad_op):
|
|
@@ -337,10 +368,10 @@ class QasmOutput:
|
|
|
337
368
|
if should_annotate:
|
|
338
369
|
output_line_gap(1)
|
|
339
370
|
if isinstance(main_op, ops.GateOperation):
|
|
340
|
-
x = str(main_op.gate).replace('\n', '\n
|
|
371
|
+
x = str(main_op.gate).replace('\n', '\n// ')
|
|
341
372
|
output(f'// Gate: {x!s}\n')
|
|
342
373
|
else:
|
|
343
|
-
x = str(main_op).replace('\n', '\n
|
|
374
|
+
x = str(main_op).replace('\n', '\n// ')
|
|
344
375
|
output(f'// Operation: {x!s}\n')
|
|
345
376
|
|
|
346
377
|
for qasm in qasms:
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
import re
|
|
15
14
|
import os
|
|
15
|
+
import re
|
|
16
|
+
|
|
16
17
|
import numpy as np
|
|
17
18
|
import pytest
|
|
18
19
|
|
|
@@ -52,6 +53,11 @@ def test_qasm_u_qubit_gate_unitary():
|
|
|
52
53
|
|
|
53
54
|
cirq.testing.assert_implements_consistent_protocols(g)
|
|
54
55
|
|
|
56
|
+
u = cirq.unitary(cirq.Y)
|
|
57
|
+
g = QasmUGate.from_matrix(u)
|
|
58
|
+
cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(g), u, atol=1e-7)
|
|
59
|
+
cirq.testing.assert_implements_consistent_protocols(g)
|
|
60
|
+
|
|
55
61
|
|
|
56
62
|
def test_qasm_two_qubit_gate_unitary():
|
|
57
63
|
u = cirq.testing.random_unitary(4)
|
|
@@ -225,7 +231,7 @@ rx(pi*0.123) q[0];
|
|
|
225
231
|
def test_version():
|
|
226
232
|
(q0,) = _make_qubits(1)
|
|
227
233
|
with pytest.raises(ValueError):
|
|
228
|
-
output = cirq.QasmOutput((), (q0,), version='
|
|
234
|
+
output = cirq.QasmOutput((), (q0,), version='4.0')
|
|
229
235
|
_ = str(output)
|
|
230
236
|
|
|
231
237
|
|
|
@@ -590,3 +596,58 @@ reset q[0];
|
|
|
590
596
|
reset q[1];
|
|
591
597
|
""".strip()
|
|
592
598
|
)
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
def test_different_sized_registers():
|
|
602
|
+
qubits = cirq.LineQubit.range(2)
|
|
603
|
+
c = cirq.Circuit(cirq.measure(qubits[0], key='c'), cirq.measure(qubits, key='c'))
|
|
604
|
+
output = cirq.QasmOutput(
|
|
605
|
+
c.all_operations(), tuple(sorted(c.all_qubits())), header='Generated from Cirq!'
|
|
606
|
+
)
|
|
607
|
+
assert (
|
|
608
|
+
str(output)
|
|
609
|
+
== """// Generated from Cirq!
|
|
610
|
+
|
|
611
|
+
OPENQASM 2.0;
|
|
612
|
+
include "qelib1.inc";
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
// Qubits: [q(0), q(1)]
|
|
616
|
+
qreg q[2];
|
|
617
|
+
creg m_c[2];
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
measure q[0] -> m_c[0];
|
|
621
|
+
|
|
622
|
+
// Gate: cirq.MeasurementGate(2, cirq.MeasurementKey(name='c'), ())
|
|
623
|
+
measure q[0] -> m_c[0];
|
|
624
|
+
measure q[1] -> m_c[1];
|
|
625
|
+
"""
|
|
626
|
+
)
|
|
627
|
+
# OPENQASM 3.0
|
|
628
|
+
output3 = cirq.QasmOutput(
|
|
629
|
+
c.all_operations(),
|
|
630
|
+
tuple(sorted(c.all_qubits())),
|
|
631
|
+
header='Generated from Cirq!',
|
|
632
|
+
version='3.0',
|
|
633
|
+
)
|
|
634
|
+
assert (
|
|
635
|
+
str(output3)
|
|
636
|
+
== """// Generated from Cirq!
|
|
637
|
+
|
|
638
|
+
OPENQASM 3.0;
|
|
639
|
+
include "stdgates.inc";
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
// Qubits: [q(0), q(1)]
|
|
643
|
+
qubit[2] q;
|
|
644
|
+
bit[2] m_c;
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
m_c[0] = measure q[0];
|
|
648
|
+
|
|
649
|
+
// Gate: cirq.MeasurementGate(2, cirq.MeasurementKey(name='c'), ())
|
|
650
|
+
m_c[0] = measure q[0];
|
|
651
|
+
m_c[1] = measure q[1];
|
|
652
|
+
"""
|
|
653
|
+
)
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
from typing import (
|
|
16
18
|
Any,
|
|
17
19
|
Callable,
|
|
@@ -25,7 +27,6 @@ from typing import (
|
|
|
25
27
|
Sequence,
|
|
26
28
|
Tuple,
|
|
27
29
|
TYPE_CHECKING,
|
|
28
|
-
Union,
|
|
29
30
|
)
|
|
30
31
|
|
|
31
32
|
import numpy as np
|
|
@@ -33,11 +34,11 @@ import numpy as np
|
|
|
33
34
|
from cirq import value
|
|
34
35
|
from cirq.circuits._block_diagram_drawer import BlockDiagramDrawer
|
|
35
36
|
from cirq.circuits._box_drawing_character_data import (
|
|
36
|
-
BoxDrawCharacterSet,
|
|
37
|
-
NORMAL_BOX_CHARS,
|
|
38
|
-
BOLD_BOX_CHARS,
|
|
39
37
|
ASCII_BOX_CHARS,
|
|
38
|
+
BOLD_BOX_CHARS,
|
|
39
|
+
BoxDrawCharacterSet,
|
|
40
40
|
DOUBLED_BOX_CHARS,
|
|
41
|
+
NORMAL_BOX_CHARS,
|
|
41
42
|
)
|
|
42
43
|
|
|
43
44
|
if TYPE_CHECKING:
|
|
@@ -45,23 +46,11 @@ if TYPE_CHECKING:
|
|
|
45
46
|
|
|
46
47
|
_HorizontalLine = NamedTuple(
|
|
47
48
|
'_HorizontalLine',
|
|
48
|
-
[
|
|
49
|
-
('y', Union[int, float]),
|
|
50
|
-
('x1', Union[int, float]),
|
|
51
|
-
('x2', Union[int, float]),
|
|
52
|
-
('emphasize', bool),
|
|
53
|
-
('doubled', bool),
|
|
54
|
-
],
|
|
49
|
+
[('y', float), ('x1', float), ('x2', float), ('emphasize', bool), ('doubled', bool)],
|
|
55
50
|
)
|
|
56
51
|
_VerticalLine = NamedTuple(
|
|
57
52
|
'_VerticalLine',
|
|
58
|
-
[
|
|
59
|
-
('x', Union[int, float]),
|
|
60
|
-
('y1', Union[int, float]),
|
|
61
|
-
('y2', Union[int, float]),
|
|
62
|
-
('emphasize', bool),
|
|
63
|
-
('doubled', bool),
|
|
64
|
-
],
|
|
53
|
+
[('x', float), ('y1', float), ('y2', float), ('emphasize', bool), ('doubled', bool)],
|
|
65
54
|
)
|
|
66
55
|
_DiagramText = NamedTuple('_DiagramText', [('text', str), ('transposed_text', str)])
|
|
67
56
|
|
|
@@ -99,10 +88,10 @@ class TextDiagramDrawer:
|
|
|
99
88
|
self.vertical_lines: List[_VerticalLine] = (
|
|
100
89
|
[] if vertical_lines is None else list(vertical_lines)
|
|
101
90
|
)
|
|
102
|
-
self.horizontal_padding: Dict[int,
|
|
91
|
+
self.horizontal_padding: Dict[int, float] = (
|
|
103
92
|
dict() if horizontal_padding is None else dict(horizontal_padding)
|
|
104
93
|
)
|
|
105
|
-
self.vertical_padding: Dict[int,
|
|
94
|
+
self.vertical_padding: Dict[int, float] = (
|
|
106
95
|
dict() if vertical_padding is None else dict(vertical_padding)
|
|
107
96
|
)
|
|
108
97
|
|
|
@@ -148,7 +137,7 @@ class TextDiagramDrawer:
|
|
|
148
137
|
|
|
149
138
|
# Horizontal line?
|
|
150
139
|
if any(line_y == y and x1 < x < x2 for line_y, x1, x2, _, _ in self.horizontal_lines):
|
|
151
|
-
return True
|
|
140
|
+
return True # pragma: no cover
|
|
152
141
|
|
|
153
142
|
return False
|
|
154
143
|
|
|
@@ -171,30 +160,20 @@ class TextDiagramDrawer:
|
|
|
171
160
|
raise ValueError("Line is neither horizontal nor vertical")
|
|
172
161
|
|
|
173
162
|
def vertical_line(
|
|
174
|
-
self,
|
|
175
|
-
x: Union[int, float],
|
|
176
|
-
y1: Union[int, float],
|
|
177
|
-
y2: Union[int, float],
|
|
178
|
-
emphasize: bool = False,
|
|
179
|
-
doubled: bool = False,
|
|
163
|
+
self, x: float, y1: float, y2: float, emphasize: bool = False, doubled: bool = False
|
|
180
164
|
) -> None:
|
|
181
165
|
"""Adds a line from (x, y1) to (x, y2)."""
|
|
182
166
|
y1, y2 = sorted([y1, y2])
|
|
183
167
|
self.vertical_lines.append(_VerticalLine(x, y1, y2, emphasize, doubled))
|
|
184
168
|
|
|
185
169
|
def horizontal_line(
|
|
186
|
-
self,
|
|
187
|
-
y: Union[int, float],
|
|
188
|
-
x1: Union[int, float],
|
|
189
|
-
x2: Union[int, float],
|
|
190
|
-
emphasize: bool = False,
|
|
191
|
-
doubled: bool = False,
|
|
170
|
+
self, y: float, x1: float, x2: float, emphasize: bool = False, doubled: bool = False
|
|
192
171
|
) -> None:
|
|
193
172
|
"""Adds a line from (x1, y) to (x2, y)."""
|
|
194
173
|
x1, x2 = sorted([x1, x2])
|
|
195
174
|
self.horizontal_lines.append(_HorizontalLine(y, x1, x2, emphasize, doubled))
|
|
196
175
|
|
|
197
|
-
def transpose(self) ->
|
|
176
|
+
def transpose(self) -> cirq.TextDiagramDrawer:
|
|
198
177
|
"""Returns the same diagram, but mirrored across its diagonal."""
|
|
199
178
|
out = TextDiagramDrawer()
|
|
200
179
|
out.entries = {
|
|
@@ -228,26 +207,21 @@ class TextDiagramDrawer:
|
|
|
228
207
|
max_y = max(max_y, v.y1, v.y2)
|
|
229
208
|
return 1 + int(max_y)
|
|
230
209
|
|
|
231
|
-
def force_horizontal_padding_after(self, index: int, padding:
|
|
210
|
+
def force_horizontal_padding_after(self, index: int, padding: float) -> None:
|
|
232
211
|
"""Change the padding after the given column."""
|
|
233
212
|
self.horizontal_padding[index] = padding
|
|
234
213
|
|
|
235
|
-
def force_vertical_padding_after(self, index: int, padding:
|
|
214
|
+
def force_vertical_padding_after(self, index: int, padding: float) -> None:
|
|
236
215
|
"""Change the padding after the given row."""
|
|
237
216
|
self.vertical_padding[index] = padding
|
|
238
217
|
|
|
239
|
-
def _transform_coordinates(
|
|
240
|
-
self,
|
|
241
|
-
func: Callable[
|
|
242
|
-
[Union[int, float], Union[int, float]], Tuple[Union[int, float], Union[int, float]]
|
|
243
|
-
],
|
|
244
|
-
) -> None:
|
|
218
|
+
def _transform_coordinates(self, func: Callable[[float, float], Tuple[float, float]]) -> None:
|
|
245
219
|
"""Helper method to transformer either row or column coordinates."""
|
|
246
220
|
|
|
247
|
-
def func_x(x:
|
|
221
|
+
def func_x(x: float) -> float:
|
|
248
222
|
return func(x, 0)[0]
|
|
249
223
|
|
|
250
|
-
def func_y(y:
|
|
224
|
+
def func_y(y: float) -> float:
|
|
251
225
|
return func(0, y)[1]
|
|
252
226
|
|
|
253
227
|
self.entries = {
|
|
@@ -271,9 +245,7 @@ class TextDiagramDrawer:
|
|
|
271
245
|
def insert_empty_columns(self, x: int, amount: int = 1) -> None:
|
|
272
246
|
"""Insert a number of columns after the given column."""
|
|
273
247
|
|
|
274
|
-
def transform_columns(
|
|
275
|
-
column: Union[int, float], row: Union[int, float]
|
|
276
|
-
) -> Tuple[Union[int, float], Union[int, float]]:
|
|
248
|
+
def transform_columns(column: float, row: float) -> Tuple[float, float]:
|
|
277
249
|
return column + (amount if column >= x else 0), row
|
|
278
250
|
|
|
279
251
|
self._transform_coordinates(transform_columns)
|
|
@@ -281,9 +253,7 @@ class TextDiagramDrawer:
|
|
|
281
253
|
def insert_empty_rows(self, y: int, amount: int = 1) -> None:
|
|
282
254
|
"""Insert a number of rows after the given row."""
|
|
283
255
|
|
|
284
|
-
def transform_rows(
|
|
285
|
-
column: Union[int, float], row: Union[int, float]
|
|
286
|
-
) -> Tuple[Union[int, float], Union[int, float]]:
|
|
256
|
+
def transform_rows(column: float, row: float) -> Tuple[float, float]:
|
|
287
257
|
return column, row + (amount if row >= y else 0)
|
|
288
258
|
|
|
289
259
|
self._transform_coordinates(transform_rows)
|
|
@@ -365,14 +335,14 @@ class TextDiagramDrawer:
|
|
|
365
335
|
horizontal_padding=self.horizontal_padding,
|
|
366
336
|
)
|
|
367
337
|
|
|
368
|
-
def shift(self, dx: int = 0, dy: int = 0) ->
|
|
338
|
+
def shift(self, dx: int = 0, dy: int = 0) -> cirq.TextDiagramDrawer:
|
|
369
339
|
self._transform_coordinates(lambda x, y: (x + dx, y + dy))
|
|
370
340
|
return self
|
|
371
341
|
|
|
372
|
-
def shifted(self, dx: int = 0, dy: int = 0) ->
|
|
342
|
+
def shifted(self, dx: int = 0, dy: int = 0) -> cirq.TextDiagramDrawer:
|
|
373
343
|
return self.copy().shift(dx, dy)
|
|
374
344
|
|
|
375
|
-
def superimpose(self, other:
|
|
345
|
+
def superimpose(self, other: cirq.TextDiagramDrawer) -> cirq.TextDiagramDrawer:
|
|
376
346
|
self.entries.update(other.entries)
|
|
377
347
|
self.horizontal_lines += other.horizontal_lines
|
|
378
348
|
self.vertical_lines += other.vertical_lines
|
|
@@ -380,13 +350,13 @@ class TextDiagramDrawer:
|
|
|
380
350
|
self.vertical_padding.update(other.vertical_padding)
|
|
381
351
|
return self
|
|
382
352
|
|
|
383
|
-
def superimposed(self, other:
|
|
353
|
+
def superimposed(self, other: cirq.TextDiagramDrawer) -> cirq.TextDiagramDrawer:
|
|
384
354
|
return self.copy().superimpose(other)
|
|
385
355
|
|
|
386
356
|
@classmethod
|
|
387
357
|
def vstack(
|
|
388
358
|
cls,
|
|
389
|
-
diagrams: Sequence[
|
|
359
|
+
diagrams: Sequence[cirq.TextDiagramDrawer],
|
|
390
360
|
padding_resolver: Optional[Callable[[Sequence[Optional[int]]], int]] = None,
|
|
391
361
|
):
|
|
392
362
|
"""Vertically stack text diagrams.
|
|
@@ -427,7 +397,7 @@ class TextDiagramDrawer:
|
|
|
427
397
|
@classmethod
|
|
428
398
|
def hstack(
|
|
429
399
|
cls,
|
|
430
|
-
diagrams: Sequence[
|
|
400
|
+
diagrams: Sequence[cirq.TextDiagramDrawer],
|
|
431
401
|
padding_resolver: Optional[Callable[[Sequence[Optional[int]]], int]] = None,
|
|
432
402
|
):
|
|
433
403
|
"""Horizontally stack text diagrams.
|
|
@@ -13,23 +13,24 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
from unittest import mock
|
|
16
|
+
|
|
16
17
|
import pytest
|
|
17
18
|
|
|
19
|
+
import cirq.testing as ct
|
|
18
20
|
from cirq.circuits import TextDiagramDrawer
|
|
19
21
|
from cirq.circuits._block_diagram_drawer_test import _assert_same_diagram
|
|
20
22
|
from cirq.circuits._box_drawing_character_data import (
|
|
21
23
|
ASCII_BOX_CHARS,
|
|
22
|
-
NORMAL_BOX_CHARS,
|
|
23
|
-
DOUBLED_BOX_CHARS,
|
|
24
24
|
BOLD_BOX_CHARS,
|
|
25
|
+
DOUBLED_BOX_CHARS,
|
|
26
|
+
NORMAL_BOX_CHARS,
|
|
25
27
|
)
|
|
26
28
|
from cirq.circuits.text_diagram_drawer import (
|
|
29
|
+
_DiagramText,
|
|
27
30
|
_HorizontalLine,
|
|
28
31
|
_VerticalLine,
|
|
29
|
-
_DiagramText,
|
|
30
32
|
pick_charset,
|
|
31
33
|
)
|
|
32
|
-
import cirq.testing as ct
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
def assert_has_rendering(actual: TextDiagramDrawer, desired: str, **kwargs) -> None:
|
cirq/contrib/__init__.py
CHANGED
|
@@ -21,6 +21,6 @@ this package.
|
|
|
21
21
|
from cirq.contrib import acquaintance
|
|
22
22
|
from cirq.contrib import graph_device
|
|
23
23
|
from cirq.contrib import quirk
|
|
24
|
-
from cirq.contrib.qcircuit import circuit_to_latex_using_qcircuit
|
|
24
|
+
from cirq.contrib.qcircuit import circuit_to_latex_using_qcircuit as circuit_to_latex_using_qcircuit
|
|
25
25
|
from cirq.contrib import json
|
|
26
|
-
from cirq.contrib.circuitdag import CircuitDag, Unique
|
|
26
|
+
from cirq.contrib.circuitdag import CircuitDag as CircuitDag, Unique as Unique
|