cirq-core 1.4.0.dev20240529225110__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/__init__.py +587 -569
- cirq/_compat.py +9 -0
- cirq/_compat_test.py +11 -9
- cirq/_import.py +7 -8
- cirq/_version.py +31 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/__init__.py +15 -9
- cirq/circuits/_block_diagram_drawer.py +1 -2
- cirq/circuits/_block_diagram_drawer_test.py +3 -3
- cirq/circuits/_box_drawing_character_data.py +0 -1
- cirq/circuits/_box_drawing_character_data_test.py +2 -2
- cirq/circuits/_bucket_priority_queue.py +0 -1
- cirq/circuits/_bucket_priority_queue_test.py +1 -1
- cirq/circuits/circuit.py +336 -234
- cirq/circuits/circuit_operation.py +102 -52
- cirq/circuits/circuit_operation_test.py +85 -4
- cirq/circuits/circuit_test.py +101 -32
- cirq/circuits/frozen_circuit.py +36 -32
- cirq/circuits/insert_strategy.py +10 -0
- cirq/circuits/insert_strategy_test.py +20 -0
- cirq/circuits/moment.py +79 -80
- cirq/circuits/moment_test.py +105 -2
- cirq/circuits/optimization_pass.py +15 -15
- cirq/circuits/optimization_pass_test.py +8 -9
- cirq/circuits/qasm_output.py +64 -33
- cirq/circuits/qasm_output_test.py +63 -2
- cirq/circuits/text_diagram_drawer.py +26 -56
- cirq/circuits/text_diagram_drawer_test.py +5 -4
- cirq/contrib/__init__.py +2 -2
- cirq/contrib/acquaintance/__init__.py +44 -29
- cirq/contrib/acquaintance/bipartite.py +8 -7
- cirq/contrib/acquaintance/bipartite_test.py +11 -1
- cirq/contrib/acquaintance/devices.py +5 -4
- cirq/contrib/acquaintance/devices_test.py +5 -1
- cirq/contrib/acquaintance/executor.py +18 -21
- cirq/contrib/acquaintance/executor_test.py +3 -2
- cirq/contrib/acquaintance/gates.py +36 -27
- cirq/contrib/acquaintance/gates_test.py +1 -1
- cirq/contrib/acquaintance/inspection_utils.py +10 -9
- cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
- cirq/contrib/acquaintance/mutation_utils.py +10 -10
- cirq/contrib/acquaintance/optimizers.py +7 -6
- cirq/contrib/acquaintance/optimizers_test.py +1 -1
- cirq/contrib/acquaintance/permutation.py +22 -21
- cirq/contrib/acquaintance/permutation_test.py +1 -1
- cirq/contrib/acquaintance/shift.py +8 -6
- cirq/contrib/acquaintance/shift_swap_network.py +6 -4
- cirq/contrib/acquaintance/strategies/__init__.py +9 -3
- cirq/contrib/acquaintance/strategies/complete.py +4 -3
- cirq/contrib/acquaintance/strategies/cubic.py +5 -3
- cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
- cirq/contrib/acquaintance/topological_sort.py +4 -2
- cirq/contrib/bayesian_network/__init__.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
- cirq/contrib/circuitdag/__init__.py +1 -1
- cirq/contrib/circuitdag/circuit_dag.py +24 -24
- cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
- cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
- cirq/contrib/graph_device/__init__.py +8 -8
- cirq/contrib/graph_device/graph_device.py +8 -8
- cirq/contrib/graph_device/graph_device_test.py +0 -1
- cirq/contrib/graph_device/hypergraph_test.py +1 -0
- cirq/contrib/json.py +1 -2
- cirq/contrib/json_test.py +2 -2
- cirq/contrib/noise_models/__init__.py +5 -6
- cirq/contrib/noise_models/noise_models.py +8 -6
- cirq/contrib/paulistring/__init__.py +22 -10
- cirq/contrib/paulistring/clifford_optimize.py +1 -1
- cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
- cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
- cirq/contrib/paulistring/optimize.py +2 -2
- cirq/contrib/paulistring/optimize_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
- cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
- cirq/contrib/paulistring/recombine.py +2 -2
- cirq/contrib/paulistring/recombine_test.py +2 -2
- cirq/contrib/paulistring/separate.py +3 -4
- cirq/contrib/qasm_import/__init__.py +2 -2
- cirq/contrib/qasm_import/_lexer.py +21 -26
- cirq/contrib/qasm_import/_lexer_test.py +90 -6
- cirq/contrib/qasm_import/_parser.py +238 -47
- cirq/contrib/qasm_import/_parser_test.py +514 -59
- cirq/contrib/qasm_import/qasm_test.py +1 -1
- cirq/contrib/qcircuit/__init__.py +6 -4
- cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
- cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
- cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
- cirq/contrib/qcircuit/qcircuit_test.py +1 -1
- cirq/contrib/quantum_volume/__init__.py +7 -7
- cirq/contrib/quantum_volume/quantum_volume.py +6 -11
- cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
- cirq/contrib/quimb/__init__.py +16 -13
- cirq/contrib/quimb/density_matrix.py +1 -1
- cirq/contrib/quimb/mps_simulator.py +27 -28
- cirq/contrib/quimb/mps_simulator_test.py +5 -0
- cirq/contrib/quimb/state_vector.py +3 -10
- cirq/contrib/quirk/__init__.py +1 -1
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/routing/__init__.py +12 -9
- cirq/contrib/routing/device.py +1 -1
- cirq/contrib/routing/device_test.py +1 -2
- cirq/contrib/routing/greedy.py +7 -5
- cirq/contrib/routing/greedy_test.py +5 -3
- cirq/contrib/routing/initialization.py +3 -1
- cirq/contrib/routing/initialization_test.py +1 -1
- cirq/contrib/routing/swap_network.py +6 -6
- cirq/contrib/routing/utils.py +6 -4
- cirq/contrib/routing/utils_test.py +1 -2
- cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
- cirq/contrib/svg/__init__.py +1 -1
- cirq/contrib/svg/svg.py +12 -10
- cirq/contrib/svg/svg_test.py +3 -2
- cirq/devices/__init__.py +34 -25
- cirq/devices/device.py +16 -12
- cirq/devices/device_test.py +1 -0
- cirq/devices/grid_device_metadata.py +16 -12
- cirq/devices/grid_device_metadata_test.py +2 -1
- cirq/devices/grid_qubit.py +31 -26
- cirq/devices/grid_qubit_test.py +30 -1
- cirq/devices/insertion_noise_model.py +6 -6
- cirq/devices/insertion_noise_model_test.py +1 -1
- cirq/devices/line_qubit.py +28 -20
- cirq/devices/line_qubit_test.py +26 -0
- cirq/devices/named_topologies.py +12 -10
- cirq/devices/named_topologies_test.py +5 -4
- cirq/devices/noise_model.py +29 -33
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +2 -2
- cirq/devices/noise_utils.py +3 -3
- cirq/devices/superconducting_qubits_noise_properties.py +2 -2
- cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
- cirq/devices/thermal_noise_model.py +2 -1
- cirq/devices/unconstrained_device.py +1 -1
- cirq/devices/unconstrained_device_test.py +6 -0
- cirq/experiments/__init__.py +51 -34
- cirq/experiments/qubit_characterizations.py +17 -15
- cirq/experiments/qubit_characterizations_test.py +4 -6
- cirq/experiments/random_quantum_circuit_generation.py +10 -9
- cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
- cirq/experiments/readout_confusion_matrix.py +73 -8
- cirq/experiments/readout_confusion_matrix_test.py +104 -1
- cirq/experiments/single_qubit_readout_calibration.py +8 -6
- cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
- cirq/experiments/t1_decay_experiment.py +4 -5
- cirq/experiments/t1_decay_experiment_test.py +1 -2
- cirq/experiments/t2_decay_experiment.py +0 -1
- cirq/experiments/t2_decay_experiment_test.py +1 -2
- cirq/experiments/two_qubit_xeb.py +157 -33
- cirq/experiments/two_qubit_xeb_test.py +38 -22
- cirq/experiments/xeb_fitting.py +99 -19
- cirq/experiments/xeb_fitting_test.py +64 -25
- cirq/experiments/xeb_sampling.py +14 -18
- cirq/experiments/xeb_simulation.py +4 -3
- cirq/experiments/xeb_simulation_test.py +20 -14
- cirq/experiments/z_phase_calibration.py +368 -0
- cirq/experiments/z_phase_calibration_test.py +241 -0
- cirq/interop/__init__.py +4 -1
- cirq/interop/quirk/__init__.py +7 -4
- cirq/interop/quirk/cells/__init__.py +17 -6
- cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
- cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
- cirq/interop/quirk/cells/cell.py +6 -6
- cirq/interop/quirk/cells/composite_cell.py +5 -5
- cirq/interop/quirk/cells/composite_cell_test.py +1 -1
- cirq/interop/quirk/cells/control_cells.py +1 -1
- cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
- cirq/interop/quirk/cells/ignored_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells_test.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
- cirq/interop/quirk/cells/measurement_cells.py +1 -1
- cirq/interop/quirk/cells/parse.py +8 -7
- cirq/interop/quirk/cells/parse_test.py +2 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/swap_cell_test.py +1 -1
- cirq/interop/quirk/cells/unsupported_cells.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +7 -7
- cirq/interop/quirk/url_to_circuit_test.py +1 -1
- cirq/ion/__init__.py +4 -2
- cirq/json_resolver_cache.py +15 -7
- cirq/linalg/__init__.py +62 -51
- cirq/linalg/combinators.py +4 -4
- cirq/linalg/combinators_test.py +4 -1
- cirq/linalg/decompositions.py +15 -40
- cirq/linalg/decompositions_test.py +16 -22
- cirq/linalg/diagonalize.py +1 -1
- cirq/linalg/diagonalize_test.py +1 -1
- cirq/linalg/operator_spaces.py +20 -4
- cirq/linalg/operator_spaces_test.py +15 -2
- cirq/linalg/predicates.py +3 -3
- cirq/linalg/predicates_test.py +1 -0
- cirq/linalg/tolerance.py +2 -2
- cirq/linalg/transformations.py +30 -12
- cirq/linalg/transformations_test.py +13 -0
- cirq/neutral_atoms/__init__.py +2 -2
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
- cirq/ops/__init__.py +172 -132
- cirq/ops/arithmetic_operation.py +2 -2
- cirq/ops/arithmetic_operation_test.py +2 -2
- cirq/ops/boolean_hamiltonian.py +3 -2
- cirq/ops/classically_controlled_operation.py +39 -12
- cirq/ops/classically_controlled_operation_test.py +147 -1
- cirq/ops/clifford_gate.py +38 -36
- cirq/ops/clifford_gate_test.py +75 -1
- cirq/ops/common_channels.py +16 -45
- cirq/ops/common_channels_test.py +10 -0
- cirq/ops/common_gate_families.py +1 -1
- cirq/ops/common_gate_families_test.py +1 -0
- cirq/ops/common_gates.py +48 -49
- cirq/ops/common_gates_test.py +18 -2
- cirq/ops/control_values.py +3 -3
- cirq/ops/control_values_test.py +2 -1
- cirq/ops/controlled_gate.py +36 -23
- cirq/ops/controlled_gate_test.py +70 -3
- cirq/ops/controlled_operation.py +6 -5
- cirq/ops/controlled_operation_test.py +7 -3
- cirq/ops/dense_pauli_string.py +11 -11
- cirq/ops/diagonal_gate.py +2 -2
- cirq/ops/diagonal_gate_test.py +1 -0
- cirq/ops/eigen_gate.py +16 -36
- cirq/ops/eigen_gate_test.py +60 -10
- cirq/ops/fourier_transform.py +1 -3
- cirq/ops/fourier_transform_test.py +2 -1
- cirq/ops/fsim_gate.py +42 -3
- cirq/ops/fsim_gate_test.py +21 -0
- cirq/ops/gate_operation.py +8 -8
- cirq/ops/gate_operation_test.py +4 -2
- cirq/ops/gateset_test.py +11 -2
- cirq/ops/global_phase_op.py +8 -7
- cirq/ops/global_phase_op_test.py +1 -1
- cirq/ops/greedy_qubit_manager_test.py +5 -0
- cirq/ops/identity.py +14 -4
- cirq/ops/identity_test.py +24 -0
- cirq/ops/kraus_channel.py +1 -0
- cirq/ops/kraus_channel_test.py +3 -1
- cirq/ops/linear_combinations.py +27 -21
- cirq/ops/linear_combinations_test.py +23 -4
- cirq/ops/matrix_gates.py +24 -8
- cirq/ops/measure_util.py +2 -2
- cirq/ops/measurement_gate.py +7 -4
- cirq/ops/measurement_gate_test.py +2 -1
- cirq/ops/mixed_unitary_channel.py +1 -0
- cirq/ops/mixed_unitary_channel_test.py +3 -1
- cirq/ops/named_qubit.py +8 -1
- cirq/ops/op_tree.py +3 -30
- cirq/ops/op_tree_test.py +4 -0
- cirq/ops/parallel_gate.py +2 -3
- cirq/ops/parallel_gate_test.py +2 -1
- cirq/ops/parity_gates.py +7 -8
- cirq/ops/parity_gates_test.py +1 -0
- cirq/ops/pauli_gates.py +5 -11
- cirq/ops/pauli_gates_test.py +1 -0
- cirq/ops/pauli_interaction_gate.py +11 -5
- cirq/ops/pauli_interaction_gate_test.py +2 -3
- cirq/ops/pauli_measurement_gate.py +6 -5
- cirq/ops/pauli_measurement_gate_test.py +1 -0
- cirq/ops/pauli_string.py +115 -130
- cirq/ops/pauli_string_phasor.py +21 -20
- cirq/ops/pauli_string_phasor_test.py +13 -3
- cirq/ops/pauli_string_raw_types.py +1 -0
- cirq/ops/pauli_string_test.py +192 -55
- cirq/ops/pauli_sum_exponential.py +3 -4
- cirq/ops/pauli_sum_exponential_test.py +0 -1
- cirq/ops/permutation_gate.py +2 -2
- cirq/ops/permutation_gate_test.py +1 -1
- cirq/ops/phased_iswap_gate.py +6 -7
- cirq/ops/phased_iswap_gate_test.py +21 -5
- cirq/ops/phased_x_gate.py +11 -25
- cirq/ops/phased_x_gate_test.py +19 -3
- cirq/ops/phased_x_z_gate.py +12 -11
- cirq/ops/projector.py +4 -5
- cirq/ops/qubit_manager.py +2 -1
- cirq/ops/qubit_manager_test.py +2 -1
- cirq/ops/qubit_order.py +1 -1
- cirq/ops/random_gate_channel.py +1 -1
- cirq/ops/random_gate_channel_test.py +0 -6
- cirq/ops/raw_types.py +146 -50
- cirq/ops/raw_types_test.py +37 -3
- cirq/ops/state_preparation_channel.py +2 -2
- cirq/ops/state_preparation_channel_test.py +2 -1
- cirq/ops/swap_gates.py +9 -4
- cirq/ops/three_qubit_gates.py +8 -8
- cirq/ops/three_qubit_gates_test.py +1 -0
- cirq/ops/two_qubit_diagonal_gate.py +4 -3
- cirq/ops/uniform_superposition_gate.py +4 -4
- cirq/ops/uniform_superposition_gate_test.py +1 -0
- cirq/ops/wait_gate.py +6 -8
- cirq/protocols/__init__.py +135 -83
- cirq/protocols/act_on_protocol.py +1 -1
- cirq/protocols/act_on_protocol_test.py +1 -1
- cirq/protocols/apply_channel_protocol.py +3 -3
- cirq/protocols/apply_mixture_protocol.py +15 -9
- cirq/protocols/apply_mixture_protocol_test.py +11 -0
- cirq/protocols/apply_unitary_protocol.py +2 -2
- cirq/protocols/apply_unitary_protocol_test.py +2 -1
- cirq/protocols/approximate_equality_protocol.py +7 -8
- cirq/protocols/approximate_equality_protocol_test.py +3 -1
- cirq/protocols/circuit_diagram_info_protocol.py +8 -6
- cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
- cirq/protocols/commutes_protocol.py +6 -6
- cirq/protocols/control_key_protocol.py +1 -1
- cirq/protocols/decompose_protocol.py +4 -5
- cirq/protocols/decompose_protocol_test.py +2 -1
- cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
- cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
- cirq/protocols/has_unitary_protocol.py +1 -1
- cirq/protocols/has_unitary_protocol_test.py +8 -7
- cirq/protocols/hash_from_pickle_test.py +120 -0
- cirq/protocols/inverse_protocol.py +1 -1
- cirq/protocols/json_serialization.py +14 -1
- cirq/protocols/json_serialization_test.py +28 -7
- cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
- cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
- cirq/protocols/json_test_data/Concat.json +19 -0
- cirq/protocols/json_test_data/Concat.repr +1 -0
- cirq/protocols/json_test_data/README.md +4 -2
- cirq/protocols/json_test_data/SympyCondition.json +60 -15
- cirq/protocols/json_test_data/SympyCondition.repr +4 -1
- cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
- cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
- cirq/protocols/json_test_data/__init__.py +1 -1
- cirq/protocols/json_test_data/sympy.And.json +13 -0
- cirq/protocols/json_test_data/sympy.And.repr +1 -0
- cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
- cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
- cirq/protocols/json_test_data/sympy.Not.json +9 -0
- cirq/protocols/json_test_data/sympy.Not.repr +1 -0
- cirq/protocols/json_test_data/sympy.Or.json +13 -0
- cirq/protocols/json_test_data/sympy.Or.repr +1 -0
- cirq/protocols/json_test_data/sympy.Xor.json +13 -0
- cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
- cirq/protocols/kraus_protocol.py +8 -8
- cirq/protocols/kraus_protocol_test.py +0 -1
- cirq/protocols/measurement_key_protocol.py +1 -1
- cirq/protocols/measurement_key_protocol_test.py +7 -7
- cirq/protocols/mixture_protocol.py +6 -4
- cirq/protocols/mixture_protocol_test.py +21 -13
- cirq/protocols/pauli_expansion_protocol.py +1 -0
- cirq/protocols/pow_protocol.py +1 -1
- cirq/protocols/qasm.py +25 -6
- cirq/protocols/qasm_test.py +17 -0
- cirq/protocols/qid_shape_protocol.py +2 -2
- cirq/protocols/resolve_parameters.py +2 -3
- cirq/protocols/resolve_parameters_test.py +2 -1
- cirq/protocols/trace_distance_bound.py +1 -1
- cirq/protocols/trace_distance_bound_test.py +1 -0
- cirq/protocols/unitary_protocol.py +3 -3
- cirq/protocols/unitary_protocol_test.py +1 -1
- cirq/qis/__init__.py +48 -35
- cirq/qis/channels_test.py +0 -9
- cirq/qis/clifford_tableau.py +46 -26
- cirq/qis/clifford_tableau_test.py +2 -1
- cirq/qis/entropy.py +115 -0
- cirq/qis/entropy_test.py +43 -0
- cirq/qis/measures.py +5 -4
- cirq/qis/measures_test.py +7 -0
- cirq/qis/noise_utils_test.py +4 -4
- cirq/qis/quantum_state_representation.py +1 -1
- cirq/qis/states.py +7 -7
- cirq/sim/__init__.py +55 -37
- cirq/sim/classical_simulator.py +7 -6
- cirq/sim/classical_simulator_test.py +3 -1
- cirq/sim/clifford/__init__.py +17 -9
- cirq/sim/clifford/clifford_simulator.py +5 -4
- cirq/sim/clifford/clifford_simulator_test.py +32 -9
- cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
- cirq/sim/density_matrix_simulator.py +3 -2
- cirq/sim/density_matrix_simulator_test.py +12 -4
- cirq/sim/density_matrix_utils.py +1 -1
- cirq/sim/mux.py +2 -2
- cirq/sim/simulation_state.py +4 -5
- cirq/sim/simulation_state_base.py +2 -2
- cirq/sim/simulation_state_test.py +1 -1
- cirq/sim/simulation_utils.py +3 -1
- cirq/sim/simulation_utils_test.py +2 -3
- cirq/sim/simulator.py +7 -6
- cirq/sim/simulator_base.py +5 -5
- cirq/sim/simulator_test.py +14 -3
- cirq/sim/sparse_simulator.py +4 -3
- cirq/sim/sparse_simulator_test.py +17 -9
- cirq/sim/state_vector.py +2 -2
- cirq/sim/state_vector_simulation_state_test.py +1 -1
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/sim/state_vector_test.py +27 -32
- cirq/study/__init__.py +27 -21
- cirq/study/flatten_expressions.py +5 -6
- cirq/study/flatten_expressions_test.py +1 -1
- cirq/study/resolver.py +14 -11
- cirq/study/resolver_test.py +10 -1
- cirq/study/result.py +3 -3
- cirq/study/sweepable.py +15 -9
- cirq/study/sweepable_test.py +27 -0
- cirq/study/sweeps.py +65 -10
- cirq/study/sweeps_test.py +123 -0
- cirq/testing/__init__.py +86 -57
- cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
- cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
- cirq/testing/circuit_compare.py +3 -4
- cirq/testing/circuit_compare_test.py +7 -8
- cirq/testing/consistent_act_on.py +3 -3
- cirq/testing/consistent_channels_test.py +2 -1
- cirq/testing/consistent_controlled_gate_op.py +3 -2
- cirq/testing/consistent_controlled_gate_op_test.py +2 -3
- cirq/testing/consistent_decomposition.py +1 -1
- cirq/testing/consistent_decomposition_test.py +1 -2
- cirq/testing/consistent_pauli_expansion_test.py +1 -1
- cirq/testing/consistent_phase_by.py +1 -1
- cirq/testing/consistent_phase_by_test.py +1 -2
- cirq/testing/consistent_protocols.py +11 -11
- cirq/testing/consistent_protocols_test.py +4 -5
- cirq/testing/consistent_qasm.py +8 -12
- cirq/testing/consistent_qasm_test.py +1 -1
- cirq/testing/consistent_resolve_parameters.py +2 -1
- cirq/testing/consistent_specified_has_unitary_test.py +1 -1
- cirq/testing/consistent_unitary.py +3 -1
- cirq/testing/consistent_unitary_test.py +3 -3
- cirq/testing/devices.py +1 -1
- cirq/testing/devices_test.py +1 -0
- cirq/testing/equals_tester.py +2 -4
- cirq/testing/equals_tester_test.py +6 -5
- cirq/testing/equivalent_basis_map.py +1 -0
- cirq/testing/equivalent_basis_map_test.py +0 -1
- cirq/testing/gate_features_test.py +5 -0
- cirq/testing/json.py +4 -4
- cirq/testing/lin_alg_utils_test.py +1 -1
- cirq/testing/order_tester.py +1 -1
- cirq/testing/order_tester_test.py +1 -1
- cirq/testing/pytest_utils.py +57 -0
- cirq/testing/pytest_utils_test.py +35 -0
- cirq/testing/random_circuit.py +2 -2
- cirq/testing/random_circuit_test.py +2 -2
- cirq/testing/routing_devices_test.py +2 -1
- cirq/testing/sample_circuits.py +1 -1
- cirq/testing/sample_gates.py +5 -4
- cirq/testing/sample_gates_test.py +2 -2
- cirq/transformers/__init__.py +101 -82
- cirq/transformers/align.py +12 -1
- cirq/transformers/align_test.py +13 -0
- cirq/transformers/analytical_decompositions/__init__.py +27 -24
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
- cirq/transformers/drop_empty_moments.py +1 -0
- cirq/transformers/drop_negligible_operations.py +1 -0
- cirq/transformers/dynamical_decoupling.py +255 -43
- cirq/transformers/dynamical_decoupling_test.py +730 -17
- cirq/transformers/eject_phased_paulis.py +29 -15
- cirq/transformers/eject_phased_paulis_test.py +3 -8
- cirq/transformers/eject_z.py +3 -2
- cirq/transformers/eject_z_test.py +3 -3
- cirq/transformers/gauge_compiling/__init__.py +25 -9
- cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
- cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
- cirq/transformers/heuristic_decompositions/__init__.py +3 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
- cirq/transformers/insertion_sort.py +64 -0
- cirq/transformers/insertion_sort_test.py +34 -0
- cirq/transformers/measurement_transformers.py +14 -1
- cirq/transformers/measurement_transformers_test.py +35 -0
- cirq/transformers/merge_k_qubit_gates.py +2 -2
- cirq/transformers/merge_single_qubit_gates.py +1 -1
- cirq/transformers/merge_single_qubit_gates_test.py +1 -1
- cirq/transformers/noise_adding.py +115 -0
- cirq/transformers/noise_adding_test.py +54 -0
- cirq/transformers/optimize_for_target_gateset.py +1 -1
- cirq/transformers/optimize_for_target_gateset_test.py +3 -2
- cirq/transformers/qubit_management_transformers.py +1 -1
- cirq/transformers/randomized_measurements.py +171 -0
- cirq/transformers/randomized_measurements_test.py +68 -0
- cirq/transformers/routing/__init__.py +14 -5
- cirq/transformers/routing/initial_mapper.py +1 -1
- cirq/transformers/routing/initial_mapper_test.py +1 -0
- cirq/transformers/routing/line_initial_mapper.py +3 -2
- cirq/transformers/routing/mapping_manager.py +2 -2
- cirq/transformers/routing/mapping_manager_test.py +2 -2
- cirq/transformers/routing/route_circuit_cqc.py +3 -2
- cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
- cirq/transformers/routing/visualize_routed_circuit.py +1 -0
- cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
- cirq/transformers/stratify.py +2 -2
- cirq/transformers/synchronize_terminal_measurements.py +2 -1
- cirq/transformers/target_gatesets/__init__.py +7 -5
- cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
- cirq/transformers/target_gatesets/cz_gateset.py +5 -1
- cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
- cirq/transformers/transformer_api.py +5 -4
- cirq/transformers/transformer_api_test.py +11 -3
- cirq/transformers/transformer_primitives.py +9 -31
- cirq/transformers/transformer_primitives_test.py +6 -5
- cirq/value/__init__.py +51 -30
- cirq/value/abc_alt.py +1 -2
- cirq/value/angle.py +2 -0
- cirq/value/classical_data.py +1 -0
- cirq/value/condition.py +149 -3
- cirq/value/condition_test.py +254 -0
- cirq/value/digits.py +1 -1
- cirq/value/duration.py +4 -4
- cirq/value/duration_test.py +2 -1
- cirq/value/linear_dict.py +85 -24
- cirq/value/linear_dict_test.py +94 -3
- cirq/value/measurement_key.py +9 -2
- cirq/value/periodic_value.py +2 -3
- cirq/value/periodic_value_test.py +5 -0
- cirq/value/probability.py +1 -0
- cirq/value/random_state.py +1 -1
- cirq/value/timestamp.py +2 -4
- cirq/value/timestamp_test.py +2 -1
- cirq/value/type_alias.py +2 -2
- cirq/value/value_equality_attr.py +14 -2
- cirq/value/value_equality_attr_test.py +1 -1
- cirq/vis/__init__.py +9 -6
- cirq/vis/density_matrix.py +1 -1
- cirq/vis/density_matrix_test.py +2 -5
- cirq/vis/heatmap.py +49 -12
- cirq/vis/heatmap_test.py +168 -4
- cirq/vis/histogram.py +1 -1
- cirq/vis/histogram_test.py +1 -2
- cirq/vis/state_histogram.py +7 -5
- cirq/vis/state_histogram_test.py +2 -2
- cirq/work/__init__.py +19 -13
- cirq/work/collector.py +2 -2
- cirq/work/observable_grouping.py +2 -2
- cirq/work/observable_measurement.py +3 -3
- cirq/work/observable_measurement_data.py +5 -2
- cirq/work/observable_measurement_test.py +8 -8
- cirq/work/observable_readout_calibration.py +2 -2
- cirq/work/observable_readout_calibration_test.py +2 -1
- cirq/work/observable_settings.py +8 -7
- cirq/work/observable_settings_test.py +3 -2
- cirq/work/pauli_sum_collector.py +1 -1
- cirq/work/sampler.py +8 -20
- cirq/work/sampler_test.py +4 -3
- cirq/work/zeros_sampler.py +1 -1
- cirq_core-1.5.0.dist-info/METADATA +125 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
- cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
- cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
- cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
- cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
cirq/linalg/decompositions.py
CHANGED
|
@@ -24,7 +24,6 @@ from typing import (
|
|
|
24
24
|
Iterable,
|
|
25
25
|
List,
|
|
26
26
|
Optional,
|
|
27
|
-
Set,
|
|
28
27
|
Tuple,
|
|
29
28
|
TYPE_CHECKING,
|
|
30
29
|
TypeVar,
|
|
@@ -32,12 +31,12 @@ from typing import (
|
|
|
32
31
|
)
|
|
33
32
|
|
|
34
33
|
import matplotlib.pyplot as plt
|
|
34
|
+
import numpy as np
|
|
35
35
|
|
|
36
36
|
# this is for older systems with matplotlib <3.2 otherwise 3d projections fail
|
|
37
37
|
from mpl_toolkits import mplot3d
|
|
38
|
-
import numpy as np
|
|
39
38
|
|
|
40
|
-
from cirq import
|
|
39
|
+
from cirq import protocols, value
|
|
41
40
|
from cirq._compat import proper_repr
|
|
42
41
|
from cirq._import import LazyLoader
|
|
43
42
|
from cirq.linalg import combinators, diagonalize, predicates, transformations
|
|
@@ -106,29 +105,6 @@ def deconstruct_single_qubit_matrix_into_angles(mat: np.ndarray) -> Tuple[float,
|
|
|
106
105
|
return right_phase + diagonal_phase, rotation * 2, bottom_phase
|
|
107
106
|
|
|
108
107
|
|
|
109
|
-
def _group_similar(items: List[T], comparer: Callable[[T, T], bool]) -> List[List[T]]:
|
|
110
|
-
"""Combines similar items into groups.
|
|
111
|
-
|
|
112
|
-
Args:
|
|
113
|
-
items: The list of items to group.
|
|
114
|
-
comparer: Determines if two items are similar.
|
|
115
|
-
|
|
116
|
-
Returns:
|
|
117
|
-
A list of groups of items.
|
|
118
|
-
"""
|
|
119
|
-
groups: List[List[T]] = []
|
|
120
|
-
used: Set[int] = set()
|
|
121
|
-
for i in range(len(items)):
|
|
122
|
-
if i not in used:
|
|
123
|
-
group = [items[i]]
|
|
124
|
-
for j in range(i + 1, len(items)):
|
|
125
|
-
if j not in used and comparer(items[i], items[j]):
|
|
126
|
-
used.add(j)
|
|
127
|
-
group.append(items[j])
|
|
128
|
-
groups.append(group)
|
|
129
|
-
return groups
|
|
130
|
-
|
|
131
|
-
|
|
132
108
|
def unitary_eig(
|
|
133
109
|
matrix: np.ndarray, check_preconditions: bool = True, atol: float = 1e-8
|
|
134
110
|
) -> Tuple[np.ndarray, np.ndarray]:
|
|
@@ -175,7 +151,6 @@ def map_eigenvalues(
|
|
|
175
151
|
Args:
|
|
176
152
|
matrix: The matrix to modify with the function.
|
|
177
153
|
func: The function to apply to the eigenvalues of the matrix.
|
|
178
|
-
rtol: Relative threshold used when separating eigenspaces.
|
|
179
154
|
atol: Absolute threshold used when separating eigenspaces.
|
|
180
155
|
|
|
181
156
|
Returns:
|
|
@@ -191,15 +166,18 @@ def map_eigenvalues(
|
|
|
191
166
|
return total
|
|
192
167
|
|
|
193
168
|
|
|
194
|
-
def kron_factor_4x4_to_2x2s(
|
|
169
|
+
def kron_factor_4x4_to_2x2s(
|
|
170
|
+
matrix: np.ndarray, rtol=1e-5, atol=1e-8
|
|
171
|
+
) -> Tuple[complex, np.ndarray, np.ndarray]:
|
|
195
172
|
"""Splits a 4x4 matrix U = kron(A, B) into A, B, and a global factor.
|
|
196
173
|
|
|
197
174
|
Requires the matrix to be the kronecker product of two 2x2 unitaries.
|
|
198
175
|
Requires the matrix to have a non-zero determinant.
|
|
199
|
-
Giving an incorrect matrix will cause garbage output.
|
|
200
176
|
|
|
201
177
|
Args:
|
|
202
178
|
matrix: The 4x4 unitary matrix to factor.
|
|
179
|
+
rtol: Per-matrix-entry relative tolerance on equality.
|
|
180
|
+
atol: Per-matrix-entry absolute tolerance on equality.
|
|
203
181
|
|
|
204
182
|
Returns:
|
|
205
183
|
A scalar factor and a pair of 2x2 unit-determinant matrices. The
|
|
@@ -232,6 +210,9 @@ def kron_factor_4x4_to_2x2s(matrix: np.ndarray) -> Tuple[complex, np.ndarray, np
|
|
|
232
210
|
f1 *= -1
|
|
233
211
|
g = -g
|
|
234
212
|
|
|
213
|
+
if not np.allclose(matrix, g * np.kron(f1, f2), rtol=rtol, atol=atol):
|
|
214
|
+
raise ValueError("Invalid 4x4 kronecker product.")
|
|
215
|
+
|
|
235
216
|
return g, f1, f2
|
|
236
217
|
|
|
237
218
|
|
|
@@ -266,7 +247,7 @@ def so4_to_magic_su2s(
|
|
|
266
247
|
raise ValueError('mat must be 4x4 special orthogonal.')
|
|
267
248
|
|
|
268
249
|
ab = combinators.dot(MAGIC, mat, MAGIC_CONJ_T)
|
|
269
|
-
_, a, b = kron_factor_4x4_to_2x2s(ab)
|
|
250
|
+
_, a, b = kron_factor_4x4_to_2x2s(ab, rtol, atol)
|
|
270
251
|
|
|
271
252
|
return a, b
|
|
272
253
|
|
|
@@ -283,13 +264,7 @@ class AxisAngleDecomposition:
|
|
|
283
264
|
rotation axis, and g is the global phase.
|
|
284
265
|
"""
|
|
285
266
|
|
|
286
|
-
def __init__(
|
|
287
|
-
self,
|
|
288
|
-
*,
|
|
289
|
-
angle: float,
|
|
290
|
-
axis: Tuple[float, float, float],
|
|
291
|
-
global_phase: Union[int, float, complex],
|
|
292
|
-
):
|
|
267
|
+
def __init__(self, *, angle: float, axis: Tuple[float, float, float], global_phase: complex):
|
|
293
268
|
if not np.isclose(np.linalg.norm(axis, 2), 1, atol=1e-8):
|
|
294
269
|
raise ValueError('Axis vector must be normalized.')
|
|
295
270
|
self.global_phase = complex(global_phase)
|
|
@@ -629,12 +604,12 @@ def scatter_plot_normalized_kak_interaction_coefficients(
|
|
|
629
604
|
>>> plt.show()
|
|
630
605
|
"""
|
|
631
606
|
show_plot = not ax
|
|
632
|
-
if
|
|
607
|
+
if ax is None:
|
|
633
608
|
fig = plt.figure()
|
|
634
609
|
ax = cast(mplot3d.axes3d.Axes3D, fig.add_subplot(1, 1, 1, projection='3d'))
|
|
635
610
|
|
|
636
611
|
def coord_transform(
|
|
637
|
-
pts: Union[List[Tuple[int, int, int]], np.ndarray]
|
|
612
|
+
pts: Union[List[Tuple[int, int, int]], np.ndarray],
|
|
638
613
|
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
639
614
|
if len(pts) == 0:
|
|
640
615
|
return np.array([]), np.array([]), np.array([])
|
|
@@ -993,7 +968,7 @@ def _canonicalize_kak_vector(k_vec: np.ndarray, atol: float) -> np.ndarray:
|
|
|
993
968
|
unitaries required to bring the KAK vector into canonical form.
|
|
994
969
|
|
|
995
970
|
Args:
|
|
996
|
-
k_vec:
|
|
971
|
+
k_vec: The KAK vector to be canonicalized. This input may be vectorized,
|
|
997
972
|
with shape (...,3), where the final axis denotes the k_vector and
|
|
998
973
|
all other axes are broadcast.
|
|
999
974
|
atol: How close x2 must be to π/4 to guarantee z2 >= 0.
|
|
@@ -18,8 +18,8 @@ import numpy as np
|
|
|
18
18
|
import pytest
|
|
19
19
|
|
|
20
20
|
import cirq
|
|
21
|
-
from cirq import value
|
|
22
|
-
from cirq import
|
|
21
|
+
from cirq import unitary_eig, value
|
|
22
|
+
from cirq.linalg.decompositions import MAGIC, MAGIC_CONJ_T
|
|
23
23
|
|
|
24
24
|
X = np.array([[0, 1], [1, 0]])
|
|
25
25
|
Y = np.array([[0, -1j], [1j, 0]])
|
|
@@ -39,15 +39,8 @@ def assert_kronecker_factorization_within_tolerance(matrix, g, f1, f2):
|
|
|
39
39
|
assert np.allclose(restored, matrix), "Can't factor kronecker product."
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def assert_kronecker_factorization_not_within_tolerance(matrix, g, f1, f2):
|
|
43
|
-
restored = g * cirq.linalg.combinators.kron(f1, f2)
|
|
44
|
-
assert np.any(np.isnan(restored) or not np.allclose(restored, matrix))
|
|
45
|
-
|
|
46
|
-
|
|
47
42
|
def assert_magic_su2_within_tolerance(mat, a, b):
|
|
48
|
-
|
|
49
|
-
MT = cirq.linalg.decompositions.MAGIC_CONJ_T
|
|
50
|
-
recon = cirq.linalg.combinators.dot(MT, cirq.linalg.combinators.kron(a, b), M)
|
|
43
|
+
recon = cirq.linalg.combinators.dot(MAGIC_CONJ_T, cirq.linalg.combinators.kron(a, b), MAGIC)
|
|
51
44
|
assert np.allclose(recon, mat), "Failed to decompose within tolerance."
|
|
52
45
|
|
|
53
46
|
|
|
@@ -149,14 +142,15 @@ def test_kron_factor_special_unitaries(f1, f2):
|
|
|
149
142
|
assert_kronecker_factorization_within_tolerance(p, g, g1, g2)
|
|
150
143
|
|
|
151
144
|
|
|
152
|
-
def
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
145
|
+
def test_kron_factor_invalid_input():
|
|
146
|
+
mats = [
|
|
147
|
+
cirq.kron_with_controls(cirq.CONTROL_TAG, X),
|
|
148
|
+
np.array([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 2, 3, 4]]),
|
|
149
|
+
np.diag([1, 1, 1, 1j]),
|
|
150
|
+
]
|
|
151
|
+
for mat in mats:
|
|
152
|
+
with pytest.raises(ValueError, match="Invalid 4x4 kronecker product"):
|
|
153
|
+
cirq.kron_factor_4x4_to_2x2s(mat)
|
|
160
154
|
|
|
161
155
|
|
|
162
156
|
def recompose_so4(a: np.ndarray, b: np.ndarray) -> np.ndarray:
|
|
@@ -165,8 +159,7 @@ def recompose_so4(a: np.ndarray, b: np.ndarray) -> np.ndarray:
|
|
|
165
159
|
assert cirq.is_special_unitary(a)
|
|
166
160
|
assert cirq.is_special_unitary(b)
|
|
167
161
|
|
|
168
|
-
|
|
169
|
-
result = np.real(cirq.dot(np.conj(magic.T), cirq.kron(a, b), magic))
|
|
162
|
+
result = np.real(cirq.dot(MAGIC_CONJ_T, cirq.kron(a, b), MAGIC))
|
|
170
163
|
assert cirq.is_orthogonal(result)
|
|
171
164
|
return result
|
|
172
165
|
|
|
@@ -656,7 +649,7 @@ def test_kak_vector_matches_vectorized():
|
|
|
656
649
|
np.testing.assert_almost_equal(actual, expected)
|
|
657
650
|
|
|
658
651
|
|
|
659
|
-
def
|
|
652
|
+
def test_kak_vector_local_invariants_random_input():
|
|
660
653
|
actual = _local_invariants_from_kak(cirq.kak_vector(_random_unitaries))
|
|
661
654
|
expected = _local_invariants_from_kak(_kak_vecs)
|
|
662
655
|
|
|
@@ -697,7 +690,7 @@ def test_kak_vector_on_weyl_chamber_face():
|
|
|
697
690
|
(np.kron(X, X), (0, 0, 0)),
|
|
698
691
|
),
|
|
699
692
|
)
|
|
700
|
-
def
|
|
693
|
+
def test_kak_vector_weyl_chamber_vertices(unitary, expected):
|
|
701
694
|
actual = cirq.kak_vector(unitary)
|
|
702
695
|
np.testing.assert_almost_equal(actual, expected)
|
|
703
696
|
|
|
@@ -741,6 +734,7 @@ def test_kak_decompose(unitary: np.ndarray):
|
|
|
741
734
|
assert len(list(circuit.all_operations())) == 8
|
|
742
735
|
|
|
743
736
|
|
|
737
|
+
@cirq.testing.retry_once_with_later_random_values
|
|
744
738
|
def test_num_two_qubit_gates_required():
|
|
745
739
|
for i in range(4):
|
|
746
740
|
assert (
|
cirq/linalg/diagonalize.py
CHANGED
cirq/linalg/diagonalize_test.py
CHANGED
cirq/linalg/operator_spaces.py
CHANGED
|
@@ -13,13 +13,17 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Utilities for manipulating linear operators as elements of vector space."""
|
|
16
|
-
from typing import Dict, Tuple
|
|
16
|
+
from typing import Dict, Tuple, TYPE_CHECKING
|
|
17
17
|
|
|
18
18
|
import numpy as np
|
|
19
|
+
import sympy
|
|
19
20
|
|
|
20
21
|
from cirq import value
|
|
21
22
|
from cirq._doc import document
|
|
22
23
|
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
import cirq
|
|
26
|
+
|
|
23
27
|
PAULI_BASIS = {
|
|
24
28
|
'I': np.eye(2),
|
|
25
29
|
'X': np.array([[0.0, 1.0], [1.0, 0.0]]),
|
|
@@ -78,8 +82,17 @@ def matrix_from_basis_coefficients(
|
|
|
78
82
|
|
|
79
83
|
|
|
80
84
|
def pow_pauli_combination(
|
|
81
|
-
ai:
|
|
82
|
-
|
|
85
|
+
ai: 'cirq.TParamValComplex',
|
|
86
|
+
ax: 'cirq.TParamValComplex',
|
|
87
|
+
ay: 'cirq.TParamValComplex',
|
|
88
|
+
az: 'cirq.TParamValComplex',
|
|
89
|
+
exponent: int,
|
|
90
|
+
) -> Tuple[
|
|
91
|
+
'cirq.TParamValComplex',
|
|
92
|
+
'cirq.TParamValComplex',
|
|
93
|
+
'cirq.TParamValComplex',
|
|
94
|
+
'cirq.TParamValComplex',
|
|
95
|
+
]:
|
|
83
96
|
"""Computes non-negative integer power of single-qubit Pauli combination.
|
|
84
97
|
|
|
85
98
|
Returns scalar coefficients bi, bx, by, bz such that
|
|
@@ -96,7 +109,10 @@ def pow_pauli_combination(
|
|
|
96
109
|
if exponent == 0:
|
|
97
110
|
return 1, 0, 0, 0
|
|
98
111
|
|
|
99
|
-
|
|
112
|
+
if any(isinstance(a, sympy.Basic) for a in [ax, ay, az]):
|
|
113
|
+
v = sympy.sqrt(ax * ax + ay * ay + az * az)
|
|
114
|
+
else:
|
|
115
|
+
v = np.sqrt(ax * ax + ay * ay + az * az).item()
|
|
100
116
|
s = (ai + v) ** exponent
|
|
101
117
|
t = (ai - v) ** exponent
|
|
102
118
|
|
|
@@ -17,6 +17,7 @@ import itertools
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
import pytest
|
|
19
19
|
import scipy.linalg
|
|
20
|
+
import sympy
|
|
20
21
|
|
|
21
22
|
import cirq
|
|
22
23
|
|
|
@@ -287,11 +288,21 @@ def test_expand_is_inverse_of_reconstruct(m1, basis):
|
|
|
287
288
|
(-1, -2, 3, 4),
|
|
288
289
|
(1j, 2j, 3j, 4j),
|
|
289
290
|
(1j, 2j, 3, 4),
|
|
291
|
+
(sympy.Symbol('i'), sympy.Symbol('x'), sympy.Symbol('y'), sympy.Symbol('z')),
|
|
292
|
+
(
|
|
293
|
+
sympy.Symbol('i') * 1j,
|
|
294
|
+
-sympy.Symbol('x'),
|
|
295
|
+
-sympy.Symbol('y') * 1j,
|
|
296
|
+
sympy.Symbol('z'),
|
|
297
|
+
),
|
|
290
298
|
),
|
|
291
299
|
(0, 1, 2, 3, 4, 5, 100, 101),
|
|
292
300
|
),
|
|
293
301
|
)
|
|
294
302
|
def test_pow_pauli_combination(coefficients, exponent):
|
|
303
|
+
is_symbolic = any(isinstance(a, sympy.Basic) for a in coefficients)
|
|
304
|
+
if is_symbolic and exponent > 2:
|
|
305
|
+
return # too slow
|
|
295
306
|
i = cirq.PAULI_BASIS['I']
|
|
296
307
|
x = cirq.PAULI_BASIS['X']
|
|
297
308
|
y = cirq.PAULI_BASIS['Y']
|
|
@@ -303,5 +314,7 @@ def test_pow_pauli_combination(coefficients, exponent):
|
|
|
303
314
|
|
|
304
315
|
bi, bx, by, bz = cirq.pow_pauli_combination(ai, ax, ay, az, exponent)
|
|
305
316
|
result = bi * i + bx * x + by * y + bz * z
|
|
306
|
-
|
|
307
|
-
|
|
317
|
+
if is_symbolic:
|
|
318
|
+
assert cirq.approx_eq(result, expected_result)
|
|
319
|
+
else:
|
|
320
|
+
assert np.allclose(result, expected_result)
|
cirq/linalg/predicates.py
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""Utility methods for checking properties of matrices."""
|
|
15
|
-
from typing import cast, List, Optional, Sequence,
|
|
15
|
+
from typing import cast, List, Optional, Sequence, Tuple, Union
|
|
16
16
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
|
|
19
|
-
from cirq.linalg import tolerance, transformations
|
|
20
19
|
from cirq import value
|
|
20
|
+
from cirq.linalg import tolerance, transformations
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def is_diagonal(matrix: np.ndarray, *, atol: float = 1e-8) -> bool:
|
|
@@ -308,7 +308,7 @@ def slice_for_qubits_equal_to(
|
|
|
308
308
|
else:
|
|
309
309
|
if little_endian_qureg_value < 0 and not qid_shape_specified:
|
|
310
310
|
# Allow negative binary numbers
|
|
311
|
-
little_endian_qureg_value &= (1 << len(target_shape)) - 1
|
|
311
|
+
little_endian_qureg_value &= (1 << len(target_shape)) - 1 # pragma: no cover
|
|
312
312
|
digits = value.big_endian_int_to_digits(little_endian_qureg_value, base=target_shape[::-1])[
|
|
313
313
|
::-1
|
|
314
314
|
]
|
cirq/linalg/predicates_test.py
CHANGED
cirq/linalg/tolerance.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility for testing approximate equality of matrices and scalars within
|
|
16
16
|
tolerances."""
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import Iterable, TYPE_CHECKING, Union
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
|
|
@@ -33,7 +33,7 @@ def all_near_zero(a: 'ArrayLike', *, atol: float = 1e-8) -> bool:
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def all_near_zero_mod(
|
|
36
|
-
a: Union[float,
|
|
36
|
+
a: Union[float, Iterable[float], np.ndarray], period: float, *, atol: float = 1e-8
|
|
37
37
|
) -> bool:
|
|
38
38
|
"""Checks if the tensor's elements are all near multiples of the period.
|
|
39
39
|
|
cirq/linalg/transformations.py
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"""Utility methods for transforming matrices or vectors."""
|
|
16
16
|
|
|
17
17
|
import dataclasses
|
|
18
|
+
import functools
|
|
18
19
|
from typing import Any, List, Optional, Sequence, Tuple, Union
|
|
19
20
|
|
|
20
21
|
import numpy as np
|
|
@@ -29,8 +30,6 @@ from cirq.linalg import predicates
|
|
|
29
30
|
# user provides a different np.array([]) value.
|
|
30
31
|
RaiseValueErrorIfNotProvided: np.ndarray = np.array([])
|
|
31
32
|
|
|
32
|
-
_NPY_MAXDIMS = 32 # Should be changed once numpy/numpy#5744 is resolved.
|
|
33
|
-
|
|
34
33
|
|
|
35
34
|
def reflection_matrix_pow(reflection_matrix: np.ndarray, exponent: float):
|
|
36
35
|
"""Raises a matrix with two opposing eigenvalues to a power.
|
|
@@ -154,7 +153,6 @@ def targeted_left_multiply(
|
|
|
154
153
|
|
|
155
154
|
all_indices = set(input_indices + data_indices + tuple(output_indices))
|
|
156
155
|
|
|
157
|
-
# TODO(#5757): remove type ignore when numpy has proper override signature.
|
|
158
156
|
return np.einsum(
|
|
159
157
|
left_matrix,
|
|
160
158
|
input_indices,
|
|
@@ -165,10 +163,8 @@ def targeted_left_multiply(
|
|
|
165
163
|
# but this is a workaround for a bug in numpy:
|
|
166
164
|
# https://github.com/numpy/numpy/issues/10926
|
|
167
165
|
optimize=len(all_indices) >= 26,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
**({'out': out} if out is not None else {}),
|
|
171
|
-
) # type: ignore
|
|
166
|
+
out=out,
|
|
167
|
+
)
|
|
172
168
|
|
|
173
169
|
|
|
174
170
|
@dataclasses.dataclass
|
|
@@ -407,13 +403,12 @@ def partial_trace(tensor: np.ndarray, keep_indices: Sequence[int]) -> np.ndarray
|
|
|
407
403
|
if not all(i < ndim for i in keep_indices):
|
|
408
404
|
raise ValueError(
|
|
409
405
|
f'keep_indices were {keep_indices} but must be in first half, '
|
|
410
|
-
f'i.e. have index less
|
|
406
|
+
f'i.e. have index less than {ndim}.'
|
|
411
407
|
)
|
|
412
408
|
keep_set = set(keep_indices)
|
|
413
409
|
keep_map = dict(zip(keep_indices, sorted(keep_indices)))
|
|
414
410
|
left_indices = [keep_map[i] if i in keep_set else i for i in range(ndim)]
|
|
415
411
|
right_indices = [ndim + i if i in keep_set else i for i in left_indices]
|
|
416
|
-
# TODO(#5757): remove type ignore when numpy has proper override signature.
|
|
417
412
|
return np.einsum(tensor, left_indices + right_indices)
|
|
418
413
|
|
|
419
414
|
|
|
@@ -422,7 +417,7 @@ class EntangledStateError(ValueError):
|
|
|
422
417
|
|
|
423
418
|
|
|
424
419
|
def partial_trace_of_state_vector_as_mixture(
|
|
425
|
-
state_vector: np.ndarray, keep_indices: List[int], *, atol:
|
|
420
|
+
state_vector: np.ndarray, keep_indices: List[int], *, atol: float = 1e-8
|
|
426
421
|
) -> Tuple[Tuple[float, np.ndarray], ...]:
|
|
427
422
|
"""Returns a mixture representing a state vector with only some qubits kept.
|
|
428
423
|
|
|
@@ -481,7 +476,7 @@ def sub_state_vector(
|
|
|
481
476
|
keep_indices: List[int],
|
|
482
477
|
*,
|
|
483
478
|
default: np.ndarray = RaiseValueErrorIfNotProvided,
|
|
484
|
-
atol:
|
|
479
|
+
atol: float = 1e-6,
|
|
485
480
|
) -> np.ndarray:
|
|
486
481
|
r"""Attempts to factor a state vector into two parts and return one of them.
|
|
487
482
|
|
|
@@ -807,6 +802,29 @@ def transpose_flattened_array(t: np.ndarray, shape: Sequence[int], axes: Sequenc
|
|
|
807
802
|
return ret
|
|
808
803
|
|
|
809
804
|
|
|
805
|
+
@functools.cache
|
|
806
|
+
def _can_numpy_support_dims(num_dims: int) -> bool:
|
|
807
|
+
try:
|
|
808
|
+
_ = np.empty((1,) * num_dims)
|
|
809
|
+
return True
|
|
810
|
+
except ValueError: # pragma: no cover
|
|
811
|
+
return False
|
|
812
|
+
|
|
813
|
+
|
|
810
814
|
def can_numpy_support_shape(shape: Sequence[int]) -> bool:
|
|
811
815
|
"""Returns whether numpy supports the given shape or not numpy/numpy#5744."""
|
|
812
|
-
return
|
|
816
|
+
return min(shape, default=0) >= 0 and _can_numpy_support_dims(len(shape))
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def phase_delta(u1: np.ndarray, u2: np.ndarray) -> complex:
|
|
820
|
+
"""Calculates the phase delta of two unitaries.
|
|
821
|
+
|
|
822
|
+
The delta is from u1 to u2. i.e. u1 * phase_delta(u1, u2) == u2.
|
|
823
|
+
|
|
824
|
+
Assumes but does not verify that inputs are valid unitaries and differ only
|
|
825
|
+
by phase.
|
|
826
|
+
"""
|
|
827
|
+
# All cells will have the same phase difference. Just choose the cell with the largest
|
|
828
|
+
# absolute value, to minimize rounding error.
|
|
829
|
+
max_index = np.unravel_index(np.abs(u1).argmax(), u1.shape)
|
|
830
|
+
return u2[max_index] / u1[max_index]
|
|
@@ -648,3 +648,16 @@ def test_transpose_flattened_array(num_dimensions):
|
|
|
648
648
|
assert np.array_equal(want, got)
|
|
649
649
|
got = linalg.transpose_flattened_array(A.reshape(shape), shape, axes).reshape(want.shape)
|
|
650
650
|
assert np.array_equal(want, got)
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
@pytest.mark.parametrize('shape, result', [((), True), (30 * (1,), True), ((-3, 1, -1), False)])
|
|
654
|
+
def test_can_numpy_support_shape(shape: tuple[int, ...], result: bool) -> None:
|
|
655
|
+
assert linalg.can_numpy_support_shape(shape) is result
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
@pytest.mark.parametrize('coeff', [1, 1j, -1, -1j, 1j**0.5, 1j**0.3])
|
|
659
|
+
def test_phase_delta(coeff):
|
|
660
|
+
u1 = cirq.testing.random_unitary(4)
|
|
661
|
+
u2 = u1 * coeff
|
|
662
|
+
np.testing.assert_almost_equal(linalg.phase_delta(u1, u2), coeff)
|
|
663
|
+
np.testing.assert_almost_equal(u1 * linalg.phase_delta(u1, u2), u2)
|
cirq/neutral_atoms/__init__.py
CHANGED
|
@@ -15,6 +15,6 @@
|
|
|
15
15
|
"""Neutral atom devices and gates."""
|
|
16
16
|
|
|
17
17
|
from cirq.neutral_atoms.convert_to_neutral_atom_gates import (
|
|
18
|
-
is_native_neutral_atom_gate,
|
|
19
|
-
is_native_neutral_atom_op,
|
|
18
|
+
is_native_neutral_atom_gate as is_native_neutral_atom_gate,
|
|
19
|
+
is_native_neutral_atom_op as is_native_neutral_atom_op,
|
|
20
20
|
)
|