cirq-core 1.6.0.dev20250520054601__py3-none-any.whl → 1.6.0.dev20250520183459__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/_compat.py +15 -17
- cirq/_compat_test.py +6 -9
- cirq/_doc.py +2 -2
- cirq/_import.py +6 -6
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/_block_diagram_drawer.py +9 -10
- cirq/circuits/_box_drawing_character_data.py +6 -8
- cirq/circuits/_bucket_priority_queue.py +7 -7
- cirq/circuits/circuit.py +118 -125
- cirq/circuits/circuit_operation.py +38 -52
- cirq/circuits/circuit_test.py +4 -4
- cirq/circuits/frozen_circuit.py +13 -23
- cirq/circuits/moment.py +23 -29
- cirq/circuits/optimization_pass.py +4 -4
- cirq/circuits/optimization_pass_test.py +4 -6
- cirq/circuits/qasm_output.py +11 -11
- cirq/circuits/text_diagram_drawer.py +21 -36
- cirq/contrib/acquaintance/bipartite.py +5 -8
- cirq/contrib/acquaintance/executor.py +5 -5
- cirq/contrib/acquaintance/executor_test.py +3 -3
- cirq/contrib/acquaintance/gates.py +16 -26
- cirq/contrib/acquaintance/gates_test.py +3 -3
- cirq/contrib/acquaintance/mutation_utils.py +4 -4
- cirq/contrib/acquaintance/optimizers.py +4 -4
- cirq/contrib/acquaintance/permutation.py +15 -27
- cirq/contrib/acquaintance/shift.py +3 -3
- cirq/contrib/acquaintance/shift_swap_network.py +4 -4
- cirq/contrib/acquaintance/strategies/cubic.py +2 -2
- cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
- cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
- cirq/contrib/circuitdag/circuit_dag.py +2 -2
- cirq/contrib/custom_simulators/custom_state_simulator.py +3 -3
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +4 -4
- cirq/contrib/graph_device/graph_device.py +5 -5
- cirq/contrib/graph_device/hypergraph.py +12 -12
- cirq/contrib/graph_device/uniform_graph_device.py +4 -4
- cirq/contrib/paulistring/clifford_optimize.py +2 -2
- cirq/contrib/paulistring/clifford_target_gateset.py +7 -7
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +31 -31
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +23 -23
- cirq/contrib/paulistring/recombine.py +3 -3
- cirq/contrib/paulistring/separate.py +2 -2
- cirq/contrib/qasm_import/_parser.py +20 -32
- cirq/contrib/qcircuit/qcircuit_diagram_info.py +3 -5
- cirq/contrib/quantum_volume/quantum_volume.py +24 -24
- cirq/contrib/quimb/density_matrix.py +12 -14
- cirq/contrib/quimb/mps_simulator.py +20 -20
- cirq/contrib/quimb/state_vector.py +6 -10
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/quirk/quirk_gate.py +15 -15
- cirq/contrib/routing/device.py +3 -3
- cirq/contrib/routing/greedy.py +10 -21
- cirq/contrib/routing/initialization.py +2 -2
- cirq/contrib/routing/swap_network.py +3 -3
- cirq/contrib/routing/utils.py +2 -2
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +8 -8
- cirq/contrib/svg/svg.py +3 -3
- cirq/devices/grid_device_metadata.py +10 -10
- cirq/devices/grid_qubit.py +20 -20
- cirq/devices/insertion_noise_model.py +5 -5
- cirq/devices/line_qubit.py +13 -13
- cirq/devices/named_topologies.py +18 -29
- cirq/devices/noise_model.py +3 -3
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +1 -3
- cirq/devices/noise_utils.py +7 -7
- cirq/devices/superconducting_qubits_noise_properties.py +21 -21
- cirq/devices/superconducting_qubits_noise_properties_test.py +5 -7
- cirq/devices/thermal_noise_model.py +14 -14
- cirq/devices/unconstrained_device.py +2 -2
- cirq/experiments/benchmarking/parallel_xeb.py +29 -31
- cirq/experiments/n_qubit_tomography.py +5 -7
- cirq/experiments/qubit_characterizations.py +29 -40
- cirq/experiments/qubit_characterizations_test.py +1 -1
- cirq/experiments/random_quantum_circuit_generation.py +19 -33
- cirq/experiments/random_quantum_circuit_generation_test.py +6 -6
- cirq/experiments/readout_confusion_matrix.py +14 -14
- cirq/experiments/single_qubit_readout_calibration.py +12 -12
- cirq/experiments/t2_decay_experiment.py +7 -7
- cirq/experiments/two_qubit_xeb.py +32 -32
- cirq/experiments/two_qubit_xeb_test.py +5 -5
- cirq/experiments/xeb_fitting.py +25 -25
- cirq/experiments/xeb_sampling.py +22 -33
- cirq/experiments/xeb_simulation.py +5 -5
- cirq/experiments/xeb_simulation_test.py +3 -3
- cirq/experiments/z_phase_calibration.py +19 -19
- cirq/interop/quirk/cells/arithmetic_cells.py +23 -36
- cirq/interop/quirk/cells/cell.py +9 -21
- cirq/interop/quirk/cells/composite_cell.py +7 -22
- cirq/interop/quirk/cells/control_cells.py +8 -8
- cirq/interop/quirk/cells/input_cells.py +4 -4
- cirq/interop/quirk/cells/input_rotation_cells.py +5 -5
- cirq/interop/quirk/cells/parse.py +20 -23
- cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -3
- cirq/interop/quirk/cells/swap_cell.py +3 -3
- cirq/interop/quirk/cells/testing.py +5 -7
- cirq/interop/quirk/url_to_circuit.py +17 -33
- cirq/json_resolver_cache.py +6 -6
- cirq/linalg/decompositions.py +20 -31
- cirq/linalg/diagonalize.py +4 -4
- cirq/linalg/diagonalize_test.py +3 -4
- cirq/linalg/operator_spaces.py +5 -5
- cirq/linalg/predicates.py +7 -7
- cirq/linalg/transformations.py +20 -20
- cirq/ops/arithmetic_operation.py +13 -15
- cirq/ops/boolean_hamiltonian.py +17 -17
- cirq/ops/classically_controlled_operation.py +13 -25
- cirq/ops/clifford_gate.py +31 -35
- cirq/ops/clifford_gate_test.py +2 -3
- cirq/ops/common_channels.py +30 -32
- cirq/ops/common_gates.py +64 -74
- cirq/ops/control_values.py +12 -12
- cirq/ops/controlled_gate.py +15 -30
- cirq/ops/controlled_gate_test.py +5 -5
- cirq/ops/controlled_operation.py +12 -25
- cirq/ops/controlled_operation_test.py +5 -5
- cirq/ops/dense_pauli_string.py +23 -34
- cirq/ops/dense_pauli_string_test.py +1 -2
- cirq/ops/diagonal_gate.py +9 -20
- cirq/ops/diagonal_gate_test.py +1 -3
- cirq/ops/eigen_gate.py +11 -23
- cirq/ops/eigen_gate_test.py +6 -8
- cirq/ops/fourier_transform.py +5 -5
- cirq/ops/fsim_gate.py +14 -14
- cirq/ops/gate_operation.py +23 -44
- cirq/ops/gateset.py +23 -37
- cirq/ops/gateset_test.py +2 -2
- cirq/ops/global_phase_op.py +8 -10
- cirq/ops/greedy_qubit_manager.py +6 -6
- cirq/ops/identity.py +9 -9
- cirq/ops/kraus_channel.py +7 -7
- cirq/ops/linear_combinations.py +29 -48
- cirq/ops/matrix_gates.py +8 -8
- cirq/ops/measure_util.py +13 -14
- cirq/ops/measurement_gate.py +18 -29
- cirq/ops/mixed_unitary_channel.py +8 -8
- cirq/ops/named_qubit.py +10 -10
- cirq/ops/op_tree.py +7 -7
- cirq/ops/parallel_gate.py +5 -5
- cirq/ops/parity_gates.py +14 -14
- cirq/ops/pauli_gates.py +8 -10
- cirq/ops/pauli_interaction_gate.py +6 -6
- cirq/ops/pauli_measurement_gate.py +11 -23
- cirq/ops/pauli_string.py +35 -52
- cirq/ops/pauli_string_phasor.py +4 -14
- cirq/ops/pauli_string_raw_types.py +3 -3
- cirq/ops/pauli_sum_exponential.py +2 -2
- cirq/ops/permutation_gate.py +4 -4
- cirq/ops/phased_iswap_gate.py +9 -9
- cirq/ops/phased_x_gate.py +10 -10
- cirq/ops/phased_x_z_gate.py +11 -11
- cirq/ops/projector.py +6 -6
- cirq/ops/qubit_manager.py +6 -6
- cirq/ops/qubit_order.py +3 -3
- cirq/ops/random_gate_channel.py +4 -4
- cirq/ops/raw_types.py +48 -70
- cirq/ops/state_preparation_channel.py +3 -3
- cirq/ops/swap_gates.py +9 -9
- cirq/ops/tags.py +2 -4
- cirq/ops/three_qubit_gates.py +20 -38
- cirq/ops/two_qubit_diagonal_gate.py +5 -5
- cirq/ops/uniform_superposition_gate.py +2 -2
- cirq/ops/wait_gate.py +5 -5
- cirq/protocols/act_on_protocol_test.py +3 -3
- cirq/protocols/apply_channel_protocol.py +8 -14
- cirq/protocols/apply_mixture_protocol.py +14 -16
- cirq/protocols/apply_mixture_protocol_test.py +5 -6
- cirq/protocols/apply_unitary_protocol.py +17 -19
- cirq/protocols/circuit_diagram_info_protocol.py +19 -30
- cirq/protocols/decompose_protocol.py +30 -34
- cirq/protocols/inverse_protocol.py +7 -7
- cirq/protocols/json_serialization.py +32 -51
- cirq/protocols/json_serialization_test.py +9 -10
- cirq/protocols/kraus_protocol.py +4 -4
- cirq/protocols/kraus_protocol_test.py +3 -3
- cirq/protocols/measurement_key_protocol.py +11 -13
- cirq/protocols/mixture_protocol.py +4 -4
- cirq/protocols/qasm.py +11 -13
- cirq/protocols/qid_shape_protocol.py +6 -8
- cirq/qis/clifford_tableau.py +12 -12
- cirq/qis/measures.py +7 -7
- cirq/qis/quantum_state_representation.py +3 -3
- cirq/qis/states.py +51 -51
- cirq/sim/classical_simulator.py +10 -10
- cirq/sim/clifford/clifford_simulator.py +6 -6
- cirq/sim/clifford/clifford_tableau_simulation_state_test.py +1 -3
- cirq/sim/clifford/stabilizer_sampler.py +4 -4
- cirq/sim/clifford/stabilizer_state_ch_form.py +3 -3
- cirq/sim/density_matrix_simulation_state.py +15 -15
- cirq/sim/density_matrix_simulator.py +11 -11
- cirq/sim/density_matrix_utils.py +9 -9
- cirq/sim/mux.py +9 -9
- cirq/sim/simulation_product_state.py +9 -9
- cirq/sim/simulation_product_state_test.py +2 -2
- cirq/sim/simulation_state.py +14 -27
- cirq/sim/simulation_state_base.py +8 -24
- cirq/sim/simulation_utils.py +3 -4
- cirq/sim/simulator.py +28 -43
- cirq/sim/simulator_base.py +12 -25
- cirq/sim/simulator_base_test.py +6 -6
- cirq/sim/simulator_test.py +7 -7
- cirq/sim/sparse_simulator.py +8 -8
- cirq/sim/state_vector.py +8 -8
- cirq/sim/state_vector_simulation_state.py +17 -17
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/study/flatten_expressions.py +12 -14
- cirq/study/resolver.py +9 -11
- cirq/study/result.py +11 -24
- cirq/study/sweepable.py +5 -5
- cirq/study/sweeps.py +27 -40
- cirq/testing/circuit_compare.py +5 -5
- cirq/testing/consistent_controlled_gate_op_test.py +7 -11
- cirq/testing/consistent_protocols.py +10 -10
- cirq/testing/consistent_protocols_test.py +7 -7
- cirq/testing/consistent_qasm.py +4 -4
- cirq/testing/consistent_qasm_test.py +2 -3
- cirq/testing/devices.py +4 -5
- cirq/testing/equals_tester.py +2 -2
- cirq/testing/equivalent_basis_map.py +4 -4
- cirq/testing/equivalent_repr_eval.py +3 -3
- cirq/testing/json.py +14 -14
- cirq/testing/logs.py +3 -3
- cirq/testing/no_identifier_qubit.py +2 -3
- cirq/testing/random_circuit.py +7 -7
- cirq/testing/random_circuit_test.py +3 -3
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +16 -16
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +13 -13
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +5 -5
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +3 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +3 -3
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +4 -4
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +6 -7
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +2 -2
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +7 -7
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +4 -4
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +7 -7
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +11 -11
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +5 -5
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +14 -14
- cirq/transformers/dynamical_decoupling.py +13 -13
- cirq/transformers/dynamical_decoupling_test.py +4 -4
- cirq/transformers/eject_phased_paulis.py +16 -16
- cirq/transformers/eject_z.py +5 -7
- cirq/transformers/gauge_compiling/gauge_compiling.py +38 -38
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -2
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +8 -8
- cirq/transformers/insertion_sort.py +5 -5
- cirq/transformers/measurement_transformers.py +14 -14
- cirq/transformers/merge_k_qubit_gates_test.py +1 -3
- cirq/transformers/merge_single_qubit_gates_test.py +1 -3
- cirq/transformers/qubit_management_transformers.py +5 -5
- cirq/transformers/routing/initial_mapper.py +4 -4
- cirq/transformers/routing/line_initial_mapper.py +9 -9
- cirq/transformers/routing/mapping_manager.py +7 -7
- cirq/transformers/routing/route_circuit_cqc.py +27 -27
- cirq/transformers/routing/visualize_routed_circuit.py +4 -4
- cirq/transformers/stratify.py +8 -8
- cirq/transformers/synchronize_terminal_measurements.py +6 -6
- cirq/transformers/target_gatesets/compilation_target_gateset.py +8 -8
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -2
- cirq/transformers/target_gatesets/cz_gateset.py +4 -4
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +5 -5
- cirq/transformers/transformer_api.py +11 -26
- cirq/transformers/transformer_primitives.py +24 -36
- cirq/transformers/transformer_primitives_test.py +3 -3
- cirq/value/classical_data.py +18 -18
- cirq/value/condition.py +8 -8
- cirq/value/digits.py +7 -7
- cirq/value/duration.py +12 -12
- cirq/value/linear_dict.py +8 -12
- cirq/value/linear_dict_test.py +2 -2
- cirq/value/measurement_key.py +8 -8
- cirq/value/product_state.py +9 -9
- cirq/value/value_equality_attr.py +4 -4
- cirq/vis/heatmap.py +23 -35
- cirq/work/collector.py +9 -17
- cirq/work/observable_grouping.py +4 -7
- cirq/work/observable_measurement.py +29 -41
- cirq/work/observable_measurement_data.py +14 -14
- cirq/work/observable_measurement_test.py +2 -2
- cirq/work/observable_settings.py +9 -10
- cirq/work/pauli_sum_collector.py +5 -5
- cirq/work/sampler.py +17 -17
- cirq/work/zeros_sampler.py +3 -3
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/RECORD +290 -290
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/WHEEL +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/top_level.txt +0 -0
cirq/ops/three_qubit_gates.py
CHANGED
|
@@ -16,19 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from typing import
|
|
20
|
-
AbstractSet,
|
|
21
|
-
Any,
|
|
22
|
-
Collection,
|
|
23
|
-
Dict,
|
|
24
|
-
Iterator,
|
|
25
|
-
List,
|
|
26
|
-
Optional,
|
|
27
|
-
Sequence,
|
|
28
|
-
Tuple,
|
|
29
|
-
TYPE_CHECKING,
|
|
30
|
-
Union,
|
|
31
|
-
)
|
|
19
|
+
from typing import AbstractSet, Any, Collection, Iterator, Sequence, TYPE_CHECKING
|
|
32
20
|
|
|
33
21
|
import numpy as np
|
|
34
22
|
import sympy
|
|
@@ -72,10 +60,10 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
72
60
|
$$
|
|
73
61
|
"""
|
|
74
62
|
|
|
75
|
-
def _eigen_components(self) ->
|
|
63
|
+
def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
|
|
76
64
|
return [(0, np.diag([1, 1, 1, 1, 1, 1, 1, 0])), (1, np.diag([0, 0, 0, 0, 0, 0, 0, 1]))]
|
|
77
65
|
|
|
78
|
-
def _trace_distance_bound_(self) ->
|
|
66
|
+
def _trace_distance_bound_(self) -> float | None:
|
|
79
67
|
if self._is_parameterized_():
|
|
80
68
|
return None
|
|
81
69
|
return abs(np.sin(self._exponent * 0.5 * np.pi))
|
|
@@ -159,7 +147,7 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
159
147
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
160
148
|
return protocols.CircuitDiagramInfo(('@', '@', '@'), exponent=self._diagram_exponent(args))
|
|
161
149
|
|
|
162
|
-
def _qasm_(self, args: cirq.QasmArgs, qubits:
|
|
150
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
|
|
163
151
|
if self._exponent != 1:
|
|
164
152
|
return None
|
|
165
153
|
|
|
@@ -191,11 +179,9 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
191
179
|
|
|
192
180
|
def controlled(
|
|
193
181
|
self,
|
|
194
|
-
num_controls:
|
|
195
|
-
control_values:
|
|
196
|
-
|
|
197
|
-
] = None,
|
|
198
|
-
control_qid_shape: Optional[Tuple[int, ...]] = None,
|
|
182
|
+
num_controls: int | None = None,
|
|
183
|
+
control_values: cv.AbstractControlValues | Sequence[int | Collection[int]] | None = None,
|
|
184
|
+
control_qid_shape: tuple[int, ...] | None = None,
|
|
199
185
|
) -> raw_types.Gate:
|
|
200
186
|
"""Returns a controlled `ZPowGate` with two additional controls.
|
|
201
187
|
|
|
@@ -238,10 +224,10 @@ class ThreeQubitDiagonalGate(raw_types.Gate):
|
|
|
238
224
|
If these values are $(x_0, x_1, \ldots , x_7)$ then the unitary
|
|
239
225
|
has diagonal values $(e^{i x_0}, e^{i x_1}, \ldots, e^{i x_7})$.
|
|
240
226
|
"""
|
|
241
|
-
self._diag_angles_radians:
|
|
227
|
+
self._diag_angles_radians: tuple[value.TParamVal, ...] = tuple(diag_angles_radians)
|
|
242
228
|
|
|
243
229
|
@property
|
|
244
|
-
def diag_angles_radians(self) ->
|
|
230
|
+
def diag_angles_radians(self) -> tuple[value.TParamVal, ...]:
|
|
245
231
|
return self._diag_angles_radians
|
|
246
232
|
|
|
247
233
|
def _is_parameterized_(self) -> bool:
|
|
@@ -380,7 +366,7 @@ class ThreeQubitDiagonalGate(raw_types.Gate):
|
|
|
380
366
|
}
|
|
381
367
|
)
|
|
382
368
|
|
|
383
|
-
def _json_dict_(self) ->
|
|
369
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
384
370
|
return protocols.obj_to_dict_helper(self, attribute_names=["diag_angles_radians"])
|
|
385
371
|
|
|
386
372
|
def __repr__(self) -> str:
|
|
@@ -411,7 +397,7 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
411
397
|
$$
|
|
412
398
|
"""
|
|
413
399
|
|
|
414
|
-
def _eigen_components(self) ->
|
|
400
|
+
def _eigen_components(self) -> list[tuple[float, np.ndarray]]:
|
|
415
401
|
return [
|
|
416
402
|
(0, linalg.block_diag(np.diag([1, 1, 1, 1, 1, 1]), np.array([[0.5, 0.5], [0.5, 0.5]]))),
|
|
417
403
|
(
|
|
@@ -422,7 +408,7 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
422
408
|
),
|
|
423
409
|
]
|
|
424
410
|
|
|
425
|
-
def _trace_distance_bound_(self) ->
|
|
411
|
+
def _trace_distance_bound_(self) -> float | None:
|
|
426
412
|
if self._is_parameterized_():
|
|
427
413
|
return None
|
|
428
414
|
return abs(np.sin(self._exponent * 0.5 * np.pi))
|
|
@@ -474,7 +460,7 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
474
460
|
('@', '@', 'X'), exponent=self._diagram_exponent(args), exponent_qubit_index=2
|
|
475
461
|
)
|
|
476
462
|
|
|
477
|
-
def _qasm_(self, args: cirq.QasmArgs, qubits:
|
|
463
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
|
|
478
464
|
if self._exponent != 1:
|
|
479
465
|
return None
|
|
480
466
|
|
|
@@ -501,11 +487,9 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
501
487
|
|
|
502
488
|
def controlled(
|
|
503
489
|
self,
|
|
504
|
-
num_controls:
|
|
505
|
-
control_values:
|
|
506
|
-
|
|
507
|
-
] = None,
|
|
508
|
-
control_qid_shape: Optional[Tuple[int, ...]] = None,
|
|
490
|
+
num_controls: int | None = None,
|
|
491
|
+
control_values: cv.AbstractControlValues | Sequence[int | Collection[int]] | None = None,
|
|
492
|
+
control_qid_shape: tuple[int, ...] | None = None,
|
|
509
493
|
) -> raw_types.Gate:
|
|
510
494
|
"""Returns a controlled `XPowGate` with two additional controls.
|
|
511
495
|
|
|
@@ -653,7 +637,7 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
653
637
|
return protocols.CircuitDiagramInfo(('@', 'swap', 'swap'))
|
|
654
638
|
return protocols.CircuitDiagramInfo(('@', '×', '×'))
|
|
655
639
|
|
|
656
|
-
def _qasm_(self, args: cirq.QasmArgs, qubits:
|
|
640
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
|
|
657
641
|
args.validate_version('2.0', '3.0')
|
|
658
642
|
return args.format('cswap {0},{1},{2};\n', qubits[0], qubits[1], qubits[2])
|
|
659
643
|
|
|
@@ -676,11 +660,9 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
676
660
|
|
|
677
661
|
def controlled(
|
|
678
662
|
self,
|
|
679
|
-
num_controls:
|
|
680
|
-
control_values:
|
|
681
|
-
|
|
682
|
-
] = None,
|
|
683
|
-
control_qid_shape: Optional[Tuple[int, ...]] = None,
|
|
663
|
+
num_controls: int | None = None,
|
|
664
|
+
control_values: cv.AbstractControlValues | Sequence[int | Collection[int]] | None = None,
|
|
665
|
+
control_qid_shape: tuple[int, ...] | None = None,
|
|
684
666
|
) -> raw_types.Gate:
|
|
685
667
|
"""Returns a controlled `SWAP` with one additional control.
|
|
686
668
|
|
|
@@ -20,7 +20,7 @@ passed as a list.
|
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
|
-
from typing import AbstractSet, Any,
|
|
23
|
+
from typing import AbstractSet, Any, Iterator, Sequence, TYPE_CHECKING
|
|
24
24
|
|
|
25
25
|
import numpy as np
|
|
26
26
|
import sympy
|
|
@@ -64,10 +64,10 @@ class TwoQubitDiagonalGate(raw_types.Gate):
|
|
|
64
64
|
If these values are $(x_0, x_1, \ldots , x_3)$ then the unitary
|
|
65
65
|
has diagonal values $(e^{i x_0}, e^{i x_1}, \ldots, e^{i x_3})$.
|
|
66
66
|
"""
|
|
67
|
-
self._diag_angles_radians:
|
|
67
|
+
self._diag_angles_radians: tuple[value.TParamVal, ...] = tuple(diag_angles_radians)
|
|
68
68
|
|
|
69
69
|
@property
|
|
70
|
-
def diag_angles_radians(self) ->
|
|
70
|
+
def diag_angles_radians(self) -> tuple[value.TParamVal, ...]:
|
|
71
71
|
return self._diag_angles_radians
|
|
72
72
|
|
|
73
73
|
def _num_qubits_(self) -> int:
|
|
@@ -91,7 +91,7 @@ class TwoQubitDiagonalGate(raw_types.Gate):
|
|
|
91
91
|
def _has_unitary_(self) -> bool:
|
|
92
92
|
return not self._is_parameterized_()
|
|
93
93
|
|
|
94
|
-
def _unitary_(self) ->
|
|
94
|
+
def _unitary_(self) -> np.ndarray | None:
|
|
95
95
|
if self._is_parameterized_():
|
|
96
96
|
return None
|
|
97
97
|
return np.diag([np.exp(1j * angle) for angle in self._diag_angles_radians])
|
|
@@ -139,5 +139,5 @@ class TwoQubitDiagonalGate(raw_types.Gate):
|
|
|
139
139
|
angles = ','.join(proper_repr(angle) for angle in self._diag_angles_radians)
|
|
140
140
|
return f'cirq.TwoQubitDiagonalGate([{angles}])'
|
|
141
141
|
|
|
142
|
-
def _json_dict_(self) ->
|
|
142
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
143
143
|
return protocols.obj_to_dict_helper(self, attribute_names=["diag_angles_radians"])
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any,
|
|
17
|
+
from typing import Any, Iterator, Sequence, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
|
|
@@ -115,7 +115,7 @@ class UniformSuperpositionGate(raw_types.Gate):
|
|
|
115
115
|
def __repr__(self) -> str:
|
|
116
116
|
return f'UniformSuperpositionGate(m_value={self._m_value}, num_qubits={self._num_qubits})'
|
|
117
117
|
|
|
118
|
-
def _json_dict_(self) ->
|
|
118
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
119
119
|
d = {}
|
|
120
120
|
d['m_value'] = self._m_value
|
|
121
121
|
d['num_qubits'] = self._num_qubits
|
cirq/ops/wait_gate.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import AbstractSet, Any,
|
|
17
|
+
from typing import AbstractSet, Any, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import protocols, value
|
|
20
20
|
from cirq.ops import raw_types
|
|
@@ -34,8 +34,8 @@ class WaitGate(raw_types.Gate):
|
|
|
34
34
|
def __init__(
|
|
35
35
|
self,
|
|
36
36
|
duration: cirq.DURATION_LIKE,
|
|
37
|
-
num_qubits:
|
|
38
|
-
qid_shape:
|
|
37
|
+
num_qubits: int | None = None,
|
|
38
|
+
qid_shape: tuple[int, ...] | None = None,
|
|
39
39
|
) -> None:
|
|
40
40
|
"""Initialize a wait gate with the given duration.
|
|
41
41
|
|
|
@@ -84,7 +84,7 @@ class WaitGate(raw_types.Gate):
|
|
|
84
84
|
qid_shape=self._qid_shape,
|
|
85
85
|
)
|
|
86
86
|
|
|
87
|
-
def _qid_shape_(self) ->
|
|
87
|
+
def _qid_shape_(self) -> tuple[int, ...]:
|
|
88
88
|
return self._qid_shape
|
|
89
89
|
|
|
90
90
|
def _has_unitary_(self) -> bool:
|
|
@@ -114,7 +114,7 @@ class WaitGate(raw_types.Gate):
|
|
|
114
114
|
def __repr__(self) -> str:
|
|
115
115
|
return f'cirq.WaitGate({repr(self.duration)})'
|
|
116
116
|
|
|
117
|
-
def _json_dict_(self) ->
|
|
117
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
118
118
|
d = protocols.obj_to_dict_helper(self, ['duration'])
|
|
119
119
|
if len(self._qid_shape) != 1:
|
|
120
120
|
d['num_qubits'] = len(self._qid_shape)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any, Sequence
|
|
17
|
+
from typing import Any, Sequence
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
import pytest
|
|
@@ -65,7 +65,7 @@ def test_act_on_fallback_errors() -> None:
|
|
|
65
65
|
def test_act_on_errors() -> None:
|
|
66
66
|
class Op(cirq.Operation):
|
|
67
67
|
@property
|
|
68
|
-
def qubits(self) ->
|
|
68
|
+
def qubits(self) -> tuple[cirq.Qid, ...]: # type: ignore[empty-body]
|
|
69
69
|
pass
|
|
70
70
|
|
|
71
71
|
def with_qubits(self, *new_qubits: cirq.Qid) -> Self: # type: ignore[empty-body]
|
|
@@ -82,7 +82,7 @@ def test_act_on_errors() -> None:
|
|
|
82
82
|
def test_qubits_not_allowed_for_operations() -> None:
|
|
83
83
|
class Op(cirq.Operation):
|
|
84
84
|
@property
|
|
85
|
-
def qubits(self) ->
|
|
85
|
+
def qubits(self) -> tuple[cirq.Qid, ...]: # type: ignore[empty-body]
|
|
86
86
|
pass
|
|
87
87
|
|
|
88
88
|
def with_qubits(self, *new_qubits: cirq.Qid) -> Self: # type: ignore[empty-body]
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
from types import NotImplementedType
|
|
20
|
-
from typing import Any, Iterable,
|
|
20
|
+
from typing import Any, Iterable, Sequence, TypeVar
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
from typing_extensions import Protocol
|
|
@@ -126,9 +126,7 @@ class SupportsApplyChannel(Protocol):
|
|
|
126
126
|
"""An object that can efficiently implement a channel."""
|
|
127
127
|
|
|
128
128
|
@doc_private
|
|
129
|
-
def _apply_channel_(
|
|
130
|
-
self, args: ApplyChannelArgs
|
|
131
|
-
) -> Union[np.ndarray, None, NotImplementedType]:
|
|
129
|
+
def _apply_channel_(self, args: ApplyChannelArgs) -> np.ndarray | None | NotImplementedType:
|
|
132
130
|
"""Efficiently applies a channel.
|
|
133
131
|
|
|
134
132
|
This method is given both the target tensor and workspace of the same
|
|
@@ -168,10 +166,8 @@ class SupportsApplyChannel(Protocol):
|
|
|
168
166
|
|
|
169
167
|
|
|
170
168
|
def apply_channel(
|
|
171
|
-
val: Any,
|
|
172
|
-
|
|
173
|
-
default: Union[np.ndarray, TDefault] = RaiseTypeErrorIfNotProvided,
|
|
174
|
-
) -> Union[np.ndarray, TDefault]:
|
|
169
|
+
val: Any, args: ApplyChannelArgs, default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided
|
|
170
|
+
) -> np.ndarray | TDefault:
|
|
175
171
|
"""High performance evolution under a channel evolution.
|
|
176
172
|
|
|
177
173
|
If `val` defines an `_apply_channel_` method, that method will be
|
|
@@ -275,7 +271,7 @@ def apply_channel(
|
|
|
275
271
|
)
|
|
276
272
|
|
|
277
273
|
|
|
278
|
-
def _apply_unitary(val: Any, args: ApplyChannelArgs) ->
|
|
274
|
+
def _apply_unitary(val: Any, args: 'ApplyChannelArgs') -> np.ndarray | None:
|
|
279
275
|
"""Attempt to use `apply_unitary` and return the result.
|
|
280
276
|
|
|
281
277
|
If `val` does not support `apply_unitary` returns None.
|
|
@@ -298,9 +294,7 @@ def _apply_unitary(val: Any, args: ApplyChannelArgs) -> Optional[np.ndarray]:
|
|
|
298
294
|
return right_result
|
|
299
295
|
|
|
300
296
|
|
|
301
|
-
def _apply_kraus(
|
|
302
|
-
kraus: Union[Tuple[np.ndarray], Sequence[Any]], args: ApplyChannelArgs
|
|
303
|
-
) -> np.ndarray:
|
|
297
|
+
def _apply_kraus(kraus: tuple[np.ndarray] | Sequence[Any], args: 'ApplyChannelArgs') -> np.ndarray:
|
|
304
298
|
"""Directly apply the kraus operators to the target tensor."""
|
|
305
299
|
# Initialize output.
|
|
306
300
|
args.out_buffer[:] = 0
|
|
@@ -315,7 +309,7 @@ def _apply_kraus(
|
|
|
315
309
|
|
|
316
310
|
|
|
317
311
|
def _apply_kraus_single_qubit(
|
|
318
|
-
kraus:
|
|
312
|
+
kraus: tuple[Any] | Sequence[Any], args: 'ApplyChannelArgs'
|
|
319
313
|
) -> np.ndarray:
|
|
320
314
|
"""Use slicing to apply single qubit channel. Only for two-level qubits."""
|
|
321
315
|
zero_left = linalg.slice_for_qubits_equal_to(args.left_axes, 0)
|
|
@@ -340,7 +334,7 @@ def _apply_kraus_single_qubit(
|
|
|
340
334
|
|
|
341
335
|
|
|
342
336
|
def _apply_kraus_multi_qubit(
|
|
343
|
-
kraus:
|
|
337
|
+
kraus: tuple[Any] | Sequence[Any], args: 'ApplyChannelArgs'
|
|
344
338
|
) -> np.ndarray:
|
|
345
339
|
"""Use numpy's einsum to apply a multi-qubit channel."""
|
|
346
340
|
qid_shape = tuple(args.target_tensor.shape[i] for i in args.left_axes)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
from types import NotImplementedType
|
|
20
|
-
from typing import Any, cast, Iterable,
|
|
20
|
+
from typing import Any, cast, Iterable, TypeVar
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
from typing_extensions import Protocol
|
|
@@ -75,7 +75,7 @@ class ApplyMixtureArgs:
|
|
|
75
75
|
auxiliary_buffer0: np.ndarray,
|
|
76
76
|
auxiliary_buffer1: np.ndarray,
|
|
77
77
|
left_axes: Iterable[int],
|
|
78
|
-
right_axes:
|
|
78
|
+
right_axes: Iterable[int] | None = None,
|
|
79
79
|
):
|
|
80
80
|
"""Args for apply mixture.
|
|
81
81
|
|
|
@@ -114,9 +114,7 @@ class SupportsApplyMixture(Protocol):
|
|
|
114
114
|
"""An object that can efficiently implement a mixture."""
|
|
115
115
|
|
|
116
116
|
@doc_private
|
|
117
|
-
def _apply_mixture_(
|
|
118
|
-
self, args: ApplyMixtureArgs
|
|
119
|
-
) -> Union[np.ndarray, None, NotImplementedType]:
|
|
117
|
+
def _apply_mixture_(self, args: ApplyMixtureArgs) -> np.ndarray | None | NotImplementedType:
|
|
120
118
|
"""Efficiently applies a mixture.
|
|
121
119
|
|
|
122
120
|
This method is given both the target tensor and workspace of the same
|
|
@@ -159,8 +157,8 @@ def apply_mixture(
|
|
|
159
157
|
val: Any,
|
|
160
158
|
args: ApplyMixtureArgs,
|
|
161
159
|
*,
|
|
162
|
-
default:
|
|
163
|
-
) ->
|
|
160
|
+
default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided,
|
|
161
|
+
) -> np.ndarray | TDefault:
|
|
164
162
|
"""High performance evolution under a mixture of unitaries evolution.
|
|
165
163
|
|
|
166
164
|
Follows the steps below to attempt to apply a mixture:
|
|
@@ -275,7 +273,7 @@ def apply_mixture(
|
|
|
275
273
|
)
|
|
276
274
|
|
|
277
275
|
|
|
278
|
-
def _validate_input(val: Any, args: ApplyMixtureArgs) ->
|
|
276
|
+
def _validate_input(val: Any, args: 'ApplyMixtureArgs') -> tuple[Any, 'ApplyMixtureArgs', bool]:
|
|
279
277
|
"""Validate args input and determine if we are operating on a
|
|
280
278
|
density matrix or a state vector.
|
|
281
279
|
"""
|
|
@@ -305,8 +303,8 @@ def _validate_input(val: Any, args: ApplyMixtureArgs) -> Tuple[Any, ApplyMixture
|
|
|
305
303
|
|
|
306
304
|
|
|
307
305
|
def _apply_unitary_strat(
|
|
308
|
-
val: Any, args: ApplyMixtureArgs, is_density_matrix: bool
|
|
309
|
-
) ->
|
|
306
|
+
val: Any, args: 'ApplyMixtureArgs', is_density_matrix: bool
|
|
307
|
+
) -> np.ndarray | None:
|
|
310
308
|
"""Attempt to use `apply_unitary` and return the result.
|
|
311
309
|
|
|
312
310
|
If `val` does not support `apply_unitary` returns None.
|
|
@@ -327,7 +325,7 @@ def _apply_unitary_strat(
|
|
|
327
325
|
right_args = ApplyUnitaryArgs(
|
|
328
326
|
target_tensor=np.conjugate(left_result),
|
|
329
327
|
available_buffer=args.auxiliary_buffer0,
|
|
330
|
-
axes=cast(
|
|
328
|
+
axes=cast(tuple[int], args.right_axes),
|
|
331
329
|
)
|
|
332
330
|
right_result = apply_unitary(val, right_args)
|
|
333
331
|
np.conjugate(right_result, out=right_result)
|
|
@@ -335,8 +333,8 @@ def _apply_unitary_strat(
|
|
|
335
333
|
|
|
336
334
|
|
|
337
335
|
def _apply_unitary_from_matrix_strat(
|
|
338
|
-
val: np.ndarray, args: ApplyMixtureArgs, is_density_matrix: bool
|
|
339
|
-
) ->
|
|
336
|
+
val: np.ndarray, args: 'ApplyMixtureArgs', is_density_matrix: bool
|
|
337
|
+
) -> np.ndarray | None:
|
|
340
338
|
"""Used to enact mixture tuples that are given as (probability, np.ndarray)
|
|
341
339
|
|
|
342
340
|
If `val` does not support `apply_unitary` returns None.
|
|
@@ -354,15 +352,15 @@ def _apply_unitary_from_matrix_strat(
|
|
|
354
352
|
linalg.targeted_left_multiply(
|
|
355
353
|
np.conjugate(matrix_tensor),
|
|
356
354
|
args.auxiliary_buffer0,
|
|
357
|
-
cast(
|
|
355
|
+
cast(tuple[int], args.right_axes),
|
|
358
356
|
out=args.target_tensor,
|
|
359
357
|
)
|
|
360
358
|
return args.target_tensor
|
|
361
359
|
|
|
362
360
|
|
|
363
361
|
def _apply_mixture_from_mixture_strat(
|
|
364
|
-
val: Any, args: ApplyMixtureArgs, is_density_matrix: bool
|
|
365
|
-
) ->
|
|
362
|
+
val: Any, args: 'ApplyMixtureArgs', is_density_matrix: bool
|
|
363
|
+
) -> np.ndarray | None:
|
|
366
364
|
"""Attempt to use unitary matrices in _mixture_ and return the result."""
|
|
367
365
|
method = getattr(val, '_mixture_', None)
|
|
368
366
|
if method is None:
|
|
@@ -11,10 +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
|
-
|
|
15
14
|
from __future__ import annotations
|
|
16
15
|
|
|
17
|
-
from typing import Any, cast, Iterable
|
|
16
|
+
from typing import Any, cast, Iterable
|
|
18
17
|
|
|
19
18
|
import numpy as np
|
|
20
19
|
import pytest
|
|
@@ -34,9 +33,9 @@ def assert_apply_mixture_returns(
|
|
|
34
33
|
val: Any,
|
|
35
34
|
rho: np.ndarray,
|
|
36
35
|
left_axes: Iterable[int],
|
|
37
|
-
right_axes:
|
|
36
|
+
right_axes: Iterable[int] | None,
|
|
38
37
|
assert_result_is_out_buf: bool = False,
|
|
39
|
-
expected_result:
|
|
38
|
+
expected_result: np.ndarray | None = None,
|
|
40
39
|
):
|
|
41
40
|
out_buf, buf0, buf1 = make_buffers(rho.shape, rho.dtype)
|
|
42
41
|
result = cirq.apply_mixture(
|
|
@@ -97,8 +96,8 @@ def test_apply_mixture_simple():
|
|
|
97
96
|
def _apply_mixture_(self, args: cirq.ApplyMixtureArgs):
|
|
98
97
|
zero_left = cirq.slice_for_qubits_equal_to(args.left_axes, 0)
|
|
99
98
|
one_left = cirq.slice_for_qubits_equal_to(args.left_axes, 1)
|
|
100
|
-
zero_right = cirq.slice_for_qubits_equal_to(cast(
|
|
101
|
-
one_right = cirq.slice_for_qubits_equal_to(cast(
|
|
99
|
+
zero_right = cirq.slice_for_qubits_equal_to(cast(tuple[int], args.right_axes), 0)
|
|
100
|
+
one_right = cirq.slice_for_qubits_equal_to(cast(tuple[int], args.right_axes), 1)
|
|
102
101
|
args.out_buffer[:] = 0
|
|
103
102
|
np.copyto(dst=args.auxiliary_buffer0, src=args.target_tensor)
|
|
104
103
|
for kraus_op in [np.sqrt(0.5) * np.eye(2, dtype=np.complex128), np.sqrt(0.5) * x]:
|
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import warnings
|
|
20
20
|
from types import EllipsisType, NotImplementedType
|
|
21
|
-
from typing import Any, cast, Iterable,
|
|
21
|
+
from typing import Any, cast, Iterable, Sequence, TYPE_CHECKING, TypeVar
|
|
22
22
|
|
|
23
23
|
import numpy as np
|
|
24
24
|
from typing_extensions import Protocol
|
|
@@ -75,7 +75,7 @@ class ApplyUnitaryArgs:
|
|
|
75
75
|
target_tensor: np.ndarray,
|
|
76
76
|
available_buffer: np.ndarray,
|
|
77
77
|
axes: Iterable[int],
|
|
78
|
-
subspaces:
|
|
78
|
+
subspaces: Sequence[tuple[int, ...]] | None = None,
|
|
79
79
|
):
|
|
80
80
|
"""Inits ApplyUnitaryArgs.
|
|
81
81
|
|
|
@@ -113,7 +113,7 @@ class ApplyUnitaryArgs:
|
|
|
113
113
|
|
|
114
114
|
@staticmethod
|
|
115
115
|
def default(
|
|
116
|
-
num_qubits:
|
|
116
|
+
num_qubits: int | None = None, *, qid_shape: tuple[int, ...] | None = None
|
|
117
117
|
) -> ApplyUnitaryArgs:
|
|
118
118
|
"""A default instance starting in state |0⟩.
|
|
119
119
|
|
|
@@ -132,14 +132,14 @@ class ApplyUnitaryArgs:
|
|
|
132
132
|
raise TypeError('Specify exactly one of num_qubits or qid_shape.')
|
|
133
133
|
if num_qubits is not None:
|
|
134
134
|
qid_shape = (2,) * num_qubits
|
|
135
|
-
qid_shape = cast(
|
|
135
|
+
qid_shape = cast(tuple[int, ...], qid_shape) # Satisfy mypy
|
|
136
136
|
num_qubits = len(qid_shape)
|
|
137
137
|
state = qis.one_hot(index=(0,) * num_qubits, shape=qid_shape, dtype=np.complex128)
|
|
138
138
|
return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
|
|
139
139
|
|
|
140
140
|
@classmethod
|
|
141
141
|
def for_unitary(
|
|
142
|
-
cls, num_qubits:
|
|
142
|
+
cls, num_qubits: int | None = None, *, qid_shape: tuple[int, ...] | None = None
|
|
143
143
|
) -> ApplyUnitaryArgs:
|
|
144
144
|
"""A default instance corresponding to an identity matrix.
|
|
145
145
|
|
|
@@ -159,7 +159,7 @@ class ApplyUnitaryArgs:
|
|
|
159
159
|
raise TypeError('Specify exactly one of num_qubits or qid_shape.')
|
|
160
160
|
if num_qubits is not None:
|
|
161
161
|
qid_shape = (2,) * num_qubits
|
|
162
|
-
qid_shape = cast(
|
|
162
|
+
qid_shape = cast(tuple[int, ...], qid_shape) # Satisfy mypy
|
|
163
163
|
num_qubits = len(qid_shape)
|
|
164
164
|
state = qis.eye_tensor(qid_shape, dtype=np.complex128)
|
|
165
165
|
return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
|
|
@@ -182,7 +182,7 @@ class ApplyUnitaryArgs:
|
|
|
182
182
|
return ApplyUnitaryArgs(target_tensor, available_buffer, range(len(self.axes)))
|
|
183
183
|
|
|
184
184
|
def _for_operation_with_qid_shape(
|
|
185
|
-
self, indices: Iterable[int], slices:
|
|
185
|
+
self, indices: Iterable[int], slices: tuple[int | slice, ...]
|
|
186
186
|
) -> ApplyUnitaryArgs:
|
|
187
187
|
"""Creates a sliced and transposed view of `self` appropriate for an
|
|
188
188
|
operation with shape `qid_shape` on qubits with the given indices.
|
|
@@ -215,7 +215,7 @@ class ApplyUnitaryArgs:
|
|
|
215
215
|
|
|
216
216
|
def subspace_index(
|
|
217
217
|
self, little_endian_bits_int: int = 0, *, big_endian_bits_int: int = 0
|
|
218
|
-
) ->
|
|
218
|
+
) -> tuple[slice | int | EllipsisType, ...]:
|
|
219
219
|
"""An index for the subspace where the target axes equal a value.
|
|
220
220
|
|
|
221
221
|
Args:
|
|
@@ -260,9 +260,7 @@ class SupportsConsistentApplyUnitary(Protocol):
|
|
|
260
260
|
"""An object that can be efficiently left-multiplied into tensors."""
|
|
261
261
|
|
|
262
262
|
@doc_private
|
|
263
|
-
def _apply_unitary_(
|
|
264
|
-
self, args: ApplyUnitaryArgs
|
|
265
|
-
) -> Union[np.ndarray, None, NotImplementedType]:
|
|
263
|
+
def _apply_unitary_(self, args: ApplyUnitaryArgs) -> np.ndarray | None | NotImplementedType:
|
|
266
264
|
"""Left-multiplies a unitary effect onto a tensor with good performance.
|
|
267
265
|
|
|
268
266
|
This method is given both the target tensor and workspace of the same
|
|
@@ -308,10 +306,10 @@ class SupportsConsistentApplyUnitary(Protocol):
|
|
|
308
306
|
def apply_unitary(
|
|
309
307
|
unitary_value: Any,
|
|
310
308
|
args: ApplyUnitaryArgs,
|
|
311
|
-
default:
|
|
309
|
+
default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided,
|
|
312
310
|
*,
|
|
313
311
|
allow_decompose: bool = True,
|
|
314
|
-
) ->
|
|
312
|
+
) -> np.ndarray | TDefault:
|
|
315
313
|
"""High performance left-multiplication of a unitary effect onto a tensor.
|
|
316
314
|
|
|
317
315
|
Applies the unitary effect of `unitary_value` to the tensor specified in
|
|
@@ -422,7 +420,7 @@ def apply_unitary(
|
|
|
422
420
|
|
|
423
421
|
def _strat_apply_unitary_from_apply_unitary(
|
|
424
422
|
unitary_value: Any, args: ApplyUnitaryArgs
|
|
425
|
-
) ->
|
|
423
|
+
) -> np.ndarray | None:
|
|
426
424
|
# Check for magic method.
|
|
427
425
|
func = getattr(unitary_value, '_apply_unitary_', None)
|
|
428
426
|
if func is None:
|
|
@@ -470,7 +468,7 @@ def _apply_unitary_from_matrix(matrix: np.ndarray, unitary_value: Any, args: App
|
|
|
470
468
|
|
|
471
469
|
def _strat_apply_unitary_from_unitary(
|
|
472
470
|
unitary_value: Any, args: ApplyUnitaryArgs
|
|
473
|
-
) ->
|
|
471
|
+
) -> np.ndarray | None:
|
|
474
472
|
# Check for magic method.
|
|
475
473
|
method = getattr(unitary_value, '_unitary_', None)
|
|
476
474
|
if method is None:
|
|
@@ -484,7 +482,7 @@ def _strat_apply_unitary_from_unitary(
|
|
|
484
482
|
return _apply_unitary_from_matrix(matrix, unitary_value, args)
|
|
485
483
|
|
|
486
484
|
|
|
487
|
-
def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) ->
|
|
485
|
+
def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> np.ndarray | None:
|
|
488
486
|
operations, qubits, _ = _try_decompose_into_operations_and_qubits(val)
|
|
489
487
|
if operations is None:
|
|
490
488
|
return NotImplemented
|
|
@@ -509,9 +507,9 @@ def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> Opt
|
|
|
509
507
|
def apply_unitaries(
|
|
510
508
|
unitary_values: Iterable[Any],
|
|
511
509
|
qubits: Sequence[cirq.Qid],
|
|
512
|
-
args:
|
|
510
|
+
args: ApplyUnitaryArgs | None = None,
|
|
513
511
|
default: Any = RaiseTypeErrorIfNotProvided,
|
|
514
|
-
) ->
|
|
512
|
+
) -> np.ndarray | None:
|
|
515
513
|
"""Apply a series of unitaries onto a state tensor.
|
|
516
514
|
|
|
517
515
|
Uses `cirq.apply_unitary` on each of the unitary values, to apply them to
|
|
@@ -647,7 +645,7 @@ def _incorporate_result_into_target(
|
|
|
647
645
|
return args.target_tensor
|
|
648
646
|
|
|
649
647
|
|
|
650
|
-
def _to_slice(subspace_def:
|
|
648
|
+
def _to_slice(subspace_def: tuple[int, ...]):
|
|
651
649
|
if len(subspace_def) < 1:
|
|
652
650
|
raise ValueError(f'Subspace {subspace_def} has zero dimensions.')
|
|
653
651
|
|