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
cirq/sim/state_vector_test.py
CHANGED
|
@@ -14,16 +14,24 @@
|
|
|
14
14
|
"""Tests for state_vector.py"""
|
|
15
15
|
|
|
16
16
|
import itertools
|
|
17
|
-
from typing import Optional
|
|
18
|
-
import
|
|
17
|
+
from typing import Iterator, Optional
|
|
18
|
+
from unittest import mock
|
|
19
19
|
|
|
20
20
|
import numpy as np
|
|
21
|
+
import pytest
|
|
21
22
|
|
|
22
23
|
import cirq
|
|
23
24
|
import cirq.testing
|
|
24
25
|
from cirq import linalg
|
|
25
26
|
|
|
26
27
|
|
|
28
|
+
@pytest.fixture
|
|
29
|
+
def use_np_transpose(request) -> Iterator[bool]:
|
|
30
|
+
value: bool = request.param
|
|
31
|
+
with mock.patch.object(linalg, 'can_numpy_support_shape', lambda shape: value):
|
|
32
|
+
yield value
|
|
33
|
+
|
|
34
|
+
|
|
27
35
|
def test_state_mixin():
|
|
28
36
|
class TestClass(cirq.StateVectorMixin):
|
|
29
37
|
def state_vector(self, copy: Optional[bool] = None) -> np.ndarray:
|
|
@@ -173,9 +181,10 @@ def test_sample_no_indices_repetitions():
|
|
|
173
181
|
)
|
|
174
182
|
|
|
175
183
|
|
|
176
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
184
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
177
185
|
def test_measure_state_computational_basis(use_np_transpose: bool):
|
|
178
|
-
|
|
186
|
+
# verify patching of can_numpy_support_shape in the use_np_transpose fixture
|
|
187
|
+
assert linalg.can_numpy_support_shape([1]) is use_np_transpose
|
|
179
188
|
results = []
|
|
180
189
|
for x in range(8):
|
|
181
190
|
initial_state = cirq.to_valid_state_vector(x, 3)
|
|
@@ -186,9 +195,8 @@ def test_measure_state_computational_basis(use_np_transpose: bool):
|
|
|
186
195
|
assert results == expected
|
|
187
196
|
|
|
188
197
|
|
|
189
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
198
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
190
199
|
def test_measure_state_reshape(use_np_transpose: bool):
|
|
191
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
192
200
|
results = []
|
|
193
201
|
for x in range(8):
|
|
194
202
|
initial_state = np.reshape(cirq.to_valid_state_vector(x, 3), [2] * 3)
|
|
@@ -199,9 +207,8 @@ def test_measure_state_reshape(use_np_transpose: bool):
|
|
|
199
207
|
assert results == expected
|
|
200
208
|
|
|
201
209
|
|
|
202
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
210
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
203
211
|
def test_measure_state_partial_indices(use_np_transpose: bool):
|
|
204
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
205
212
|
for index in range(3):
|
|
206
213
|
for x in range(8):
|
|
207
214
|
initial_state = cirq.to_valid_state_vector(x, 3)
|
|
@@ -210,9 +217,8 @@ def test_measure_state_partial_indices(use_np_transpose: bool):
|
|
|
210
217
|
assert bits == [bool(1 & (x >> (2 - index)))]
|
|
211
218
|
|
|
212
219
|
|
|
213
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
220
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
214
221
|
def test_measure_state_partial_indices_order(use_np_transpose: bool):
|
|
215
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
216
222
|
for x in range(8):
|
|
217
223
|
initial_state = cirq.to_valid_state_vector(x, 3)
|
|
218
224
|
bits, state = cirq.measure_state_vector(initial_state, [2, 1])
|
|
@@ -220,9 +226,8 @@ def test_measure_state_partial_indices_order(use_np_transpose: bool):
|
|
|
220
226
|
assert bits == [bool(1 & (x >> 0)), bool(1 & (x >> 1))]
|
|
221
227
|
|
|
222
228
|
|
|
223
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
229
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
224
230
|
def test_measure_state_partial_indices_all_orders(use_np_transpose: bool):
|
|
225
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
226
231
|
for perm in itertools.permutations([0, 1, 2]):
|
|
227
232
|
for x in range(8):
|
|
228
233
|
initial_state = cirq.to_valid_state_vector(x, 3)
|
|
@@ -231,9 +236,8 @@ def test_measure_state_partial_indices_all_orders(use_np_transpose: bool):
|
|
|
231
236
|
assert bits == [bool(1 & (x >> (2 - p))) for p in perm]
|
|
232
237
|
|
|
233
238
|
|
|
234
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
239
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
235
240
|
def test_measure_state_collapse(use_np_transpose: bool):
|
|
236
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
237
241
|
initial_state = np.zeros(8, dtype=np.complex64)
|
|
238
242
|
initial_state[0] = 1 / np.sqrt(2)
|
|
239
243
|
initial_state[2] = 1 / np.sqrt(2)
|
|
@@ -256,9 +260,8 @@ def test_measure_state_collapse(use_np_transpose: bool):
|
|
|
256
260
|
assert bits == [False]
|
|
257
261
|
|
|
258
262
|
|
|
259
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
263
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
260
264
|
def test_measure_state_seed(use_np_transpose: bool):
|
|
261
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
262
265
|
n = 10
|
|
263
266
|
initial_state = np.ones(2**n) / 2 ** (n / 2)
|
|
264
267
|
|
|
@@ -277,9 +280,8 @@ def test_measure_state_seed(use_np_transpose: bool):
|
|
|
277
280
|
np.testing.assert_allclose(state1, state2)
|
|
278
281
|
|
|
279
282
|
|
|
280
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
283
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
281
284
|
def test_measure_state_out_is_state(use_np_transpose: bool):
|
|
282
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
283
285
|
initial_state = np.zeros(8, dtype=np.complex64)
|
|
284
286
|
initial_state[0] = 1 / np.sqrt(2)
|
|
285
287
|
initial_state[2] = 1 / np.sqrt(2)
|
|
@@ -290,9 +292,8 @@ def test_measure_state_out_is_state(use_np_transpose: bool):
|
|
|
290
292
|
assert state is initial_state
|
|
291
293
|
|
|
292
294
|
|
|
293
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
295
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
294
296
|
def test_measure_state_out_is_not_state(use_np_transpose: bool):
|
|
295
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
296
297
|
initial_state = np.zeros(8, dtype=np.complex64)
|
|
297
298
|
initial_state[0] = 1 / np.sqrt(2)
|
|
298
299
|
initial_state[2] = 1 / np.sqrt(2)
|
|
@@ -302,18 +303,16 @@ def test_measure_state_out_is_not_state(use_np_transpose: bool):
|
|
|
302
303
|
assert out is state
|
|
303
304
|
|
|
304
305
|
|
|
305
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
306
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
306
307
|
def test_measure_state_not_power_of_two(use_np_transpose: bool):
|
|
307
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
308
308
|
with pytest.raises(ValueError, match='3'):
|
|
309
309
|
_, _ = cirq.measure_state_vector(np.array([1, 0, 0]), [1])
|
|
310
310
|
with pytest.raises(ValueError, match='5'):
|
|
311
311
|
cirq.measure_state_vector(np.array([0, 1, 0, 0, 0]), [1])
|
|
312
312
|
|
|
313
313
|
|
|
314
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
314
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
315
315
|
def test_measure_state_index_out_of_range(use_np_transpose: bool):
|
|
316
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
317
316
|
state = cirq.to_valid_state_vector(0, 3)
|
|
318
317
|
with pytest.raises(IndexError, match='-2'):
|
|
319
318
|
cirq.measure_state_vector(state, [-2])
|
|
@@ -321,18 +320,16 @@ def test_measure_state_index_out_of_range(use_np_transpose: bool):
|
|
|
321
320
|
cirq.measure_state_vector(state, [3])
|
|
322
321
|
|
|
323
322
|
|
|
324
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
323
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
325
324
|
def test_measure_state_no_indices(use_np_transpose: bool):
|
|
326
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
327
325
|
initial_state = cirq.to_valid_state_vector(0, 3)
|
|
328
326
|
bits, state = cirq.measure_state_vector(initial_state, [])
|
|
329
327
|
assert [] == bits
|
|
330
328
|
np.testing.assert_almost_equal(state, initial_state)
|
|
331
329
|
|
|
332
330
|
|
|
333
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
331
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
334
332
|
def test_measure_state_no_indices_out_is_state(use_np_transpose: bool):
|
|
335
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
336
333
|
initial_state = cirq.to_valid_state_vector(0, 3)
|
|
337
334
|
bits, state = cirq.measure_state_vector(initial_state, [], out=initial_state)
|
|
338
335
|
assert [] == bits
|
|
@@ -340,9 +337,8 @@ def test_measure_state_no_indices_out_is_state(use_np_transpose: bool):
|
|
|
340
337
|
assert state is initial_state
|
|
341
338
|
|
|
342
339
|
|
|
343
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
340
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
344
341
|
def test_measure_state_no_indices_out_is_not_state(use_np_transpose: bool):
|
|
345
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
346
342
|
initial_state = cirq.to_valid_state_vector(0, 3)
|
|
347
343
|
out = np.zeros_like(initial_state)
|
|
348
344
|
bits, state = cirq.measure_state_vector(initial_state, [], out=out)
|
|
@@ -352,9 +348,8 @@ def test_measure_state_no_indices_out_is_not_state(use_np_transpose: bool):
|
|
|
352
348
|
assert out is not initial_state
|
|
353
349
|
|
|
354
350
|
|
|
355
|
-
@pytest.mark.parametrize('use_np_transpose', [False, True])
|
|
351
|
+
@pytest.mark.parametrize('use_np_transpose', [False, True], indirect=True)
|
|
356
352
|
def test_measure_state_empty_state(use_np_transpose: bool):
|
|
357
|
-
linalg.can_numpy_support_shape = lambda s: use_np_transpose
|
|
358
353
|
initial_state = np.array([1.0])
|
|
359
354
|
bits, state = cirq.measure_state_vector(initial_state, [])
|
|
360
355
|
assert [] == bits
|
cirq/study/__init__.py
CHANGED
|
@@ -15,33 +15,39 @@
|
|
|
15
15
|
"""Parameterized circuits and results."""
|
|
16
16
|
|
|
17
17
|
from cirq.study.flatten_expressions import (
|
|
18
|
-
ExpressionMap,
|
|
19
|
-
flatten,
|
|
20
|
-
flatten_with_params,
|
|
21
|
-
flatten_with_sweep,
|
|
18
|
+
ExpressionMap as ExpressionMap,
|
|
19
|
+
flatten as flatten,
|
|
20
|
+
flatten_with_params as flatten_with_params,
|
|
21
|
+
flatten_with_sweep as flatten_with_sweep,
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
from cirq.study.resolver import (
|
|
25
|
-
ParamDictType,
|
|
26
|
-
ParamMappingType,
|
|
27
|
-
ParamResolver,
|
|
28
|
-
ParamResolverOrSimilarType,
|
|
25
|
+
ParamDictType as ParamDictType,
|
|
26
|
+
ParamMappingType as ParamMappingType,
|
|
27
|
+
ParamResolver as ParamResolver,
|
|
28
|
+
ParamResolverOrSimilarType as ParamResolverOrSimilarType,
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
from cirq.study.sweepable import
|
|
31
|
+
from cirq.study.sweepable import (
|
|
32
|
+
Sweepable as Sweepable,
|
|
33
|
+
to_resolvers as to_resolvers,
|
|
34
|
+
to_sweep as to_sweep,
|
|
35
|
+
to_sweeps as to_sweeps,
|
|
36
|
+
)
|
|
32
37
|
|
|
33
38
|
from cirq.study.sweeps import (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
Concat as Concat,
|
|
40
|
+
Linspace as Linspace,
|
|
41
|
+
ListSweep as ListSweep,
|
|
42
|
+
Points as Points,
|
|
43
|
+
Product as Product,
|
|
44
|
+
Sweep as Sweep,
|
|
45
|
+
UNIT_SWEEP as UNIT_SWEEP,
|
|
46
|
+
UnitSweep as UnitSweep,
|
|
47
|
+
Zip as Zip,
|
|
48
|
+
ZipLongest as ZipLongest,
|
|
49
|
+
dict_to_product_sweep as dict_to_product_sweep,
|
|
50
|
+
dict_to_zip_sweep as dict_to_zip_sweep,
|
|
45
51
|
)
|
|
46
52
|
|
|
47
|
-
from cirq.study.result import ResultDict, Result
|
|
53
|
+
from cirq.study.result import ResultDict as ResultDict, Result as Result
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""Resolves symbolic expressions to unique symbols."""
|
|
15
15
|
|
|
16
|
-
from typing import Any, Callable, List, Optional, Tuple, Union, TYPE_CHECKING
|
|
17
16
|
import numbers
|
|
17
|
+
from typing import Any, Callable, List, Optional, Tuple, TYPE_CHECKING, Union
|
|
18
18
|
|
|
19
19
|
import sympy
|
|
20
20
|
|
|
21
21
|
from cirq import protocols
|
|
22
|
-
from cirq.study import resolver,
|
|
22
|
+
from cirq.study import resolver, sweepable, sweeps
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
25
|
import cirq
|
|
@@ -225,8 +225,7 @@ class _ParamFlattener(resolver.ParamResolver):
|
|
|
225
225
|
params = param_dict if param_dict else {}
|
|
226
226
|
# TODO: Support complex values for typing below.
|
|
227
227
|
symbol_params: resolver.ParamDictType = {
|
|
228
|
-
_ensure_not_str(param): _ensure_not_str(val)
|
|
229
|
-
for param, val in params.items()
|
|
228
|
+
_ensure_not_str(param): _ensure_not_str(val) for param, val in params.items()
|
|
230
229
|
}
|
|
231
230
|
super().__init__(symbol_params)
|
|
232
231
|
if get_param_name is None:
|
|
@@ -270,7 +269,7 @@ class _ParamFlattener(resolver.ParamResolver):
|
|
|
270
269
|
The unique symbol or value of the parameter as resolved by this
|
|
271
270
|
resolver.
|
|
272
271
|
"""
|
|
273
|
-
if isinstance(value,
|
|
272
|
+
if isinstance(value, numbers.Complex):
|
|
274
273
|
return value
|
|
275
274
|
if isinstance(value, str):
|
|
276
275
|
value = sympy.Symbol(value)
|
|
@@ -381,7 +380,7 @@ class ExpressionMap(dict):
|
|
|
381
380
|
|
|
382
381
|
|
|
383
382
|
def _ensure_not_str(
|
|
384
|
-
param: Union[sympy.Expr, 'cirq.TParamValComplex', str]
|
|
383
|
+
param: Union[sympy.Expr, 'cirq.TParamValComplex', str],
|
|
385
384
|
) -> Union[sympy.Expr, 'cirq.TParamValComplex']:
|
|
386
385
|
if isinstance(param, str):
|
|
387
386
|
return sympy.Symbol(param)
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import sympy
|
|
16
|
+
|
|
16
17
|
import cirq
|
|
17
18
|
from cirq.study import flatten_expressions
|
|
18
19
|
|
|
19
|
-
|
|
20
20
|
# None of the following tests use expressions of the form
|
|
21
21
|
# <constant term> - <other term> because the string of expressions containing
|
|
22
22
|
# exactly two terms, one constant term and one non-constant term with a negative
|
cirq/study/resolver.py
CHANGED
|
@@ -19,6 +19,7 @@ from typing import Any, cast, Dict, Iterator, Mapping, Optional, TYPE_CHECKING,
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
import sympy
|
|
21
21
|
from sympy.core import numbers as sympy_numbers
|
|
22
|
+
|
|
22
23
|
from cirq._compat import proper_repr
|
|
23
24
|
from cirq._doc import document
|
|
24
25
|
|
|
@@ -43,10 +44,6 @@ _NOT_FOUND = object()
|
|
|
43
44
|
_RECURSION_FLAG = object()
|
|
44
45
|
|
|
45
46
|
|
|
46
|
-
def _is_param_resolver_or_similar_type(obj: Any):
|
|
47
|
-
return obj is None or isinstance(obj, (ParamResolver, dict))
|
|
48
|
-
|
|
49
|
-
|
|
50
47
|
class ParamResolver:
|
|
51
48
|
"""Resolves parameters to actual values.
|
|
52
49
|
|
|
@@ -139,10 +136,10 @@ class ParamResolver:
|
|
|
139
136
|
if isinstance(param_value, str):
|
|
140
137
|
param_value = sympy.Symbol(param_value)
|
|
141
138
|
elif not isinstance(param_value, sympy.Basic):
|
|
142
|
-
return value
|
|
139
|
+
return value
|
|
143
140
|
if recursive:
|
|
144
141
|
param_value = self._value_of_recursive(value)
|
|
145
|
-
return param_value
|
|
142
|
+
return param_value
|
|
146
143
|
|
|
147
144
|
if not isinstance(value, sympy.Basic):
|
|
148
145
|
# No known way to resolve this variable, return unchanged.
|
|
@@ -207,7 +204,7 @@ class ParamResolver:
|
|
|
207
204
|
|
|
208
205
|
# There isn't a full evaluation for 'value' yet. Until it's ready,
|
|
209
206
|
# map value to None to identify loops in component evaluation.
|
|
210
|
-
self._deep_eval_map[value] = _RECURSION_FLAG
|
|
207
|
+
self._deep_eval_map[value] = _RECURSION_FLAG
|
|
211
208
|
|
|
212
209
|
v = self.value_of(value, recursive=False)
|
|
213
210
|
if v == value:
|
|
@@ -220,10 +217,8 @@ class ParamResolver:
|
|
|
220
217
|
new_dict: Dict['cirq.TParamKey', Union[float, str, sympy.Symbol, sympy.Expr]] = {
|
|
221
218
|
k: k for k in resolver
|
|
222
219
|
}
|
|
223
|
-
new_dict.update({k: self.value_of(k, recursive) for k in self})
|
|
224
|
-
new_dict.update(
|
|
225
|
-
{k: resolver.value_of(v, recursive) for k, v in new_dict.items()} # type: ignore[misc]
|
|
226
|
-
)
|
|
220
|
+
new_dict.update({k: self.value_of(k, recursive) for k in self})
|
|
221
|
+
new_dict.update({k: resolver.value_of(v, recursive) for k, v in new_dict.items()})
|
|
227
222
|
if recursive and self._param_dict:
|
|
228
223
|
new_resolver = ParamResolver(cast(ParamDictType, new_dict))
|
|
229
224
|
# Resolve down to single-step mappings.
|
|
@@ -246,6 +241,14 @@ class ParamResolver:
|
|
|
246
241
|
self._param_hash = hash(frozenset(self._param_dict.items()))
|
|
247
242
|
return self._param_hash
|
|
248
243
|
|
|
244
|
+
def __getstate__(self) -> Dict[str, Any]:
|
|
245
|
+
# clear cached hash value when pickling, see #6674
|
|
246
|
+
state = self.__dict__
|
|
247
|
+
if state["_param_hash"] is not None:
|
|
248
|
+
state = state.copy()
|
|
249
|
+
state["_param_hash"] = None
|
|
250
|
+
return state
|
|
251
|
+
|
|
249
252
|
def __eq__(self, other):
|
|
250
253
|
if not isinstance(other, ParamResolver):
|
|
251
254
|
return NotImplemented
|
cirq/study/resolver_test.py
CHANGED
|
@@ -84,7 +84,7 @@ def _assert_consistent_resolution(v, resolved):
|
|
|
84
84
|
|
|
85
85
|
# note: super().subs() doesn't resolve based on the param_dict properly
|
|
86
86
|
# for some reason, that's why a delegate (self.symbol) is used instead
|
|
87
|
-
def subs(self, *args, **kwargs):
|
|
87
|
+
def subs(self, *args, **kwargs): # pragma: no cover
|
|
88
88
|
self.called = True
|
|
89
89
|
return self.symbol.subs(*args, **kwargs)
|
|
90
90
|
|
|
@@ -93,6 +93,7 @@ def _assert_consistent_resolution(v, resolved):
|
|
|
93
93
|
# symbol based resolution
|
|
94
94
|
s = SubsAwareSymbol('a')
|
|
95
95
|
assert r.value_of(s) == resolved, f"expected {resolved}, got {r.value_of(s)}"
|
|
96
|
+
assert r[s] == resolved, f"expected {resolved}, got {r.value_of(s)}"
|
|
96
97
|
assert not s.called, f"For pass-through type {type(v)} sympy.subs shouldn't have been called."
|
|
97
98
|
assert isinstance(
|
|
98
99
|
r.value_of(s), type(resolved)
|
|
@@ -183,6 +184,14 @@ def test_recursive_evaluation():
|
|
|
183
184
|
assert sympy.Eq(r.value_of(e), 0)
|
|
184
185
|
|
|
185
186
|
|
|
187
|
+
def test_resolution_of_unknown_formulas():
|
|
188
|
+
a = sympy.Symbol('a')
|
|
189
|
+
b = sympy.Symbol('b')
|
|
190
|
+
|
|
191
|
+
r = cirq.ParamResolver({a: b - 2})
|
|
192
|
+
assert r.value_of(sympy.sin(a), recursive=False) == sympy.sin(b - 2)
|
|
193
|
+
|
|
194
|
+
|
|
186
195
|
def test_unbound_recursion_halted():
|
|
187
196
|
a = sympy.Symbol('a')
|
|
188
197
|
b = sympy.Symbol('b')
|
cirq/study/result.py
CHANGED
|
@@ -19,22 +19,22 @@ import io
|
|
|
19
19
|
from typing import (
|
|
20
20
|
Any,
|
|
21
21
|
Callable,
|
|
22
|
+
cast,
|
|
22
23
|
Dict,
|
|
23
24
|
Iterable,
|
|
24
25
|
Mapping,
|
|
25
26
|
Optional,
|
|
26
27
|
Sequence,
|
|
27
|
-
TYPE_CHECKING,
|
|
28
28
|
Tuple,
|
|
29
|
+
TYPE_CHECKING,
|
|
29
30
|
TypeVar,
|
|
30
31
|
Union,
|
|
31
|
-
cast,
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
import numpy as np
|
|
35
35
|
import pandas as pd
|
|
36
36
|
|
|
37
|
-
from cirq import
|
|
37
|
+
from cirq import ops, value
|
|
38
38
|
from cirq._compat import proper_repr
|
|
39
39
|
from cirq.study import resolver
|
|
40
40
|
|
cirq/study/sweepable.py
CHANGED
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
|
|
15
15
|
"""Defines which types are Sweepable."""
|
|
16
16
|
|
|
17
|
-
from typing import Iterable, Iterator, List, Sequence, Union, cast
|
|
18
17
|
import warnings
|
|
18
|
+
from typing import cast, Iterable, Iterator, List, Optional, Sequence, Union
|
|
19
|
+
|
|
19
20
|
from typing_extensions import Protocol
|
|
20
21
|
|
|
21
22
|
from cirq._doc import document
|
|
22
23
|
from cirq.study.resolver import ParamResolver, ParamResolverOrSimilarType
|
|
23
|
-
from cirq.study.sweeps import ListSweep, Points, Sweep, UnitSweep, Zip
|
|
24
|
+
from cirq.study.sweeps import dict_to_product_sweep, ListSweep, Points, Sweep, UnitSweep, Zip
|
|
24
25
|
|
|
25
26
|
SweepLike = Union[ParamResolverOrSimilarType, Sweep]
|
|
26
27
|
document(SweepLike, """An object similar to an iterable of parameter resolvers.""")
|
|
@@ -44,12 +45,12 @@ def to_resolvers(sweepable: Sweepable) -> Iterator[ParamResolver]:
|
|
|
44
45
|
yield from sweep
|
|
45
46
|
|
|
46
47
|
|
|
47
|
-
def to_sweeps(sweepable: Sweepable) -> List[Sweep]:
|
|
48
|
+
def to_sweeps(sweepable: Sweepable, metadata: Optional[dict] = None) -> List[Sweep]:
|
|
48
49
|
"""Converts a Sweepable to a list of Sweeps."""
|
|
49
50
|
if sweepable is None:
|
|
50
51
|
return [UnitSweep]
|
|
51
52
|
if isinstance(sweepable, ParamResolver):
|
|
52
|
-
return [_resolver_to_sweep(sweepable)]
|
|
53
|
+
return [_resolver_to_sweep(sweepable, metadata)]
|
|
53
54
|
if isinstance(sweepable, Sweep):
|
|
54
55
|
return [sweepable]
|
|
55
56
|
if isinstance(sweepable, dict):
|
|
@@ -63,16 +64,16 @@ def to_sweeps(sweepable: Sweepable) -> List[Sweep]:
|
|
|
63
64
|
stacklevel=2,
|
|
64
65
|
)
|
|
65
66
|
product_sweep = dict_to_product_sweep(sweepable)
|
|
66
|
-
return [_resolver_to_sweep(resolver) for resolver in product_sweep]
|
|
67
|
+
return [_resolver_to_sweep(resolver, metadata) for resolver in product_sweep]
|
|
67
68
|
if isinstance(sweepable, Iterable) and not isinstance(sweepable, str):
|
|
68
|
-
return [sweep for item in sweepable for sweep in to_sweeps(item)]
|
|
69
|
+
return [sweep for item in sweepable for sweep in to_sweeps(item, metadata)]
|
|
69
70
|
raise TypeError(f'Unrecognized sweepable type: {type(sweepable)}.\nsweepable: {sweepable}')
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
def to_sweep(
|
|
73
74
|
sweep_or_resolver_list: Union[
|
|
74
75
|
'Sweep', ParamResolverOrSimilarType, Iterable[ParamResolverOrSimilarType]
|
|
75
|
-
]
|
|
76
|
+
],
|
|
76
77
|
) -> 'Sweep':
|
|
77
78
|
"""Converts the argument into a ``cirq.Sweep``.
|
|
78
79
|
|
|
@@ -98,8 +99,13 @@ def to_sweep(
|
|
|
98
99
|
raise TypeError(f'Unexpected sweep-like value: {sweep_or_resolver_list}')
|
|
99
100
|
|
|
100
101
|
|
|
101
|
-
def _resolver_to_sweep(resolver: ParamResolver) -> Sweep:
|
|
102
|
+
def _resolver_to_sweep(resolver: ParamResolver, metadata: Optional[dict]) -> Sweep:
|
|
102
103
|
params = resolver.param_dict
|
|
103
104
|
if not params:
|
|
104
105
|
return UnitSweep
|
|
105
|
-
return Zip(
|
|
106
|
+
return Zip(
|
|
107
|
+
*[
|
|
108
|
+
Points(key, [cast(float, value)], metadata=metadata.get(key) if metadata else None)
|
|
109
|
+
for key, value in params.items()
|
|
110
|
+
]
|
|
111
|
+
)
|
cirq/study/sweepable_test.py
CHANGED
|
@@ -147,3 +147,30 @@ def test_to_sweep_resolver_list(r_list_gen):
|
|
|
147
147
|
def test_to_sweep_type_error():
|
|
148
148
|
with pytest.raises(TypeError, match='Unexpected sweep'):
|
|
149
149
|
cirq.to_sweep(5)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_to_sweeps_with_param_dict_appends_metadata():
|
|
153
|
+
params = {'a': 1, 'b': 2, 'c': 3}
|
|
154
|
+
unit_map = {'a': 'ns', 'b': 'ns'}
|
|
155
|
+
|
|
156
|
+
sweep = cirq.to_sweeps(params, unit_map)
|
|
157
|
+
|
|
158
|
+
assert sweep == [
|
|
159
|
+
cirq.Zip(
|
|
160
|
+
cirq.Points('a', [1], metadata='ns'),
|
|
161
|
+
cirq.Points('b', [2], metadata='ns'),
|
|
162
|
+
cirq.Points('c', [3]),
|
|
163
|
+
)
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_to_sweeps_with_param_list_appends_metadata():
|
|
168
|
+
resolvers = [cirq.ParamResolver({'a': 2}), cirq.ParamResolver({'a': 1})]
|
|
169
|
+
unit_map = {'a': 'ns'}
|
|
170
|
+
|
|
171
|
+
sweeps = cirq.study.to_sweeps(resolvers, unit_map)
|
|
172
|
+
|
|
173
|
+
assert sweeps == [
|
|
174
|
+
cirq.Zip(cirq.Points('a', [2], metadata='ns')),
|
|
175
|
+
cirq.Zip(cirq.Points('a', [1], metadata='ns')),
|
|
176
|
+
]
|
cirq/study/sweeps.py
CHANGED
|
@@ -11,6 +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 abc
|
|
15
|
+
import collections
|
|
16
|
+
import itertools
|
|
14
17
|
from typing import (
|
|
15
18
|
Any,
|
|
16
19
|
cast,
|
|
@@ -21,14 +24,11 @@ from typing import (
|
|
|
21
24
|
Optional,
|
|
22
25
|
overload,
|
|
23
26
|
Sequence,
|
|
24
|
-
TYPE_CHECKING,
|
|
25
27
|
Tuple,
|
|
28
|
+
TYPE_CHECKING,
|
|
26
29
|
Union,
|
|
27
30
|
)
|
|
28
31
|
|
|
29
|
-
import abc
|
|
30
|
-
import collections
|
|
31
|
-
import itertools
|
|
32
32
|
import sympy
|
|
33
33
|
|
|
34
34
|
from cirq import protocols
|
|
@@ -216,7 +216,8 @@ class Product(Sweep):
|
|
|
216
216
|
If one sweep assigns 'a' to the values 0, 1, 2, and the second sweep
|
|
217
217
|
assigns 'b' to the values 2, 3, then the product is a sweep that
|
|
218
218
|
assigns the tuple ('a','b') to all possible combinations of these
|
|
219
|
-
assignments: (0, 2), (
|
|
219
|
+
assignments: (0, 2), (0, 3), (1, 2), (1, 3), (2, 2), (2, 3).
|
|
220
|
+
That is, the leftmost sweep is the outer loop in a product of sweeps.
|
|
220
221
|
"""
|
|
221
222
|
|
|
222
223
|
def __init__(self, *factors: Sweep) -> None:
|
|
@@ -276,6 +277,63 @@ class Product(Sweep):
|
|
|
276
277
|
return Product(*factors)
|
|
277
278
|
|
|
278
279
|
|
|
280
|
+
class Concat(Sweep):
|
|
281
|
+
"""Concatenates multiple to a new sweep.
|
|
282
|
+
|
|
283
|
+
All sweeps must share the same descriptors.
|
|
284
|
+
|
|
285
|
+
If one sweep assigns 'a' to the values 0, 1, 2, and another sweep assigns
|
|
286
|
+
'a' to the values 3, 4, 5, the concatenation produces a sweep assigning
|
|
287
|
+
'a' to the values 0, 1, 2, 3, 4, 5 in sequence.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
def __init__(self, *sweeps: Sweep) -> None:
|
|
291
|
+
if not sweeps:
|
|
292
|
+
raise ValueError("Concat requires at least one sweep.")
|
|
293
|
+
|
|
294
|
+
# Validate consistency across sweeps
|
|
295
|
+
first_sweep = sweeps[0]
|
|
296
|
+
for sweep in sweeps[1:]:
|
|
297
|
+
if sweep.keys != first_sweep.keys:
|
|
298
|
+
raise ValueError("All sweeps must have the same descriptors.")
|
|
299
|
+
|
|
300
|
+
self.sweeps = sweeps
|
|
301
|
+
|
|
302
|
+
def __eq__(self, other):
|
|
303
|
+
if not isinstance(other, Concat):
|
|
304
|
+
return NotImplemented
|
|
305
|
+
return self.sweeps == other.sweeps
|
|
306
|
+
|
|
307
|
+
def __hash__(self):
|
|
308
|
+
return hash(tuple(self.sweeps))
|
|
309
|
+
|
|
310
|
+
@property
|
|
311
|
+
def keys(self) -> List['cirq.TParamKey']:
|
|
312
|
+
return self.sweeps[0].keys
|
|
313
|
+
|
|
314
|
+
def __len__(self) -> int:
|
|
315
|
+
return sum(len(sweep) for sweep in self.sweeps)
|
|
316
|
+
|
|
317
|
+
def param_tuples(self) -> Iterator[Params]:
|
|
318
|
+
for sweep in self.sweeps:
|
|
319
|
+
yield from sweep.param_tuples()
|
|
320
|
+
|
|
321
|
+
def __repr__(self) -> str:
|
|
322
|
+
sweeps_repr = ', '.join(repr(sweep) for sweep in self.sweeps)
|
|
323
|
+
return f'cirq.Concat({sweeps_repr})'
|
|
324
|
+
|
|
325
|
+
def __str__(self) -> str:
|
|
326
|
+
sweeps_repr = ', '.join(repr(s) for s in self.sweeps)
|
|
327
|
+
return f'Concat({sweeps_repr})'
|
|
328
|
+
|
|
329
|
+
def _json_dict_(self) -> Dict[str, Any]:
|
|
330
|
+
return protocols.obj_to_dict_helper(self, ['sweeps'])
|
|
331
|
+
|
|
332
|
+
@classmethod
|
|
333
|
+
def _from_json_dict_(cls, sweeps, **kwargs):
|
|
334
|
+
return Concat(*sweeps)
|
|
335
|
+
|
|
336
|
+
|
|
279
337
|
class Zip(Sweep):
|
|
280
338
|
"""Zip product (direct sum) of one or more sweeps.
|
|
281
339
|
|
|
@@ -346,7 +404,7 @@ class ZipLongest(Zip):
|
|
|
346
404
|
which uses a fixed fill value.
|
|
347
405
|
|
|
348
406
|
Raises:
|
|
349
|
-
ValueError if an input sweep
|
|
407
|
+
ValueError if an input sweep is completely empty.
|
|
350
408
|
"""
|
|
351
409
|
|
|
352
410
|
def __init__(self, *sweeps: Sweep) -> None:
|
|
@@ -589,10 +647,7 @@ def dict_to_product_sweep(factor_dict: ProductOrZipSweepLike) -> Product:
|
|
|
589
647
|
Cartesian product of the sweeps.
|
|
590
648
|
"""
|
|
591
649
|
return Product(
|
|
592
|
-
*(
|
|
593
|
-
Points(k, v if isinstance(v, Sequence) else [v]) # type: ignore
|
|
594
|
-
for k, v in factor_dict.items()
|
|
595
|
-
)
|
|
650
|
+
*(Points(k, v if isinstance(v, Sequence) else [v]) for k, v in factor_dict.items())
|
|
596
651
|
)
|
|
597
652
|
|
|
598
653
|
|