cirq-core 1.6.0.dev20250416221104__py3-none-any.whl → 1.6.0.dev20250418235304__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/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/devices/noise_model_test.py +3 -1
- cirq/devices/noise_properties.py +6 -4
- cirq/devices/noise_utils.py +8 -6
- cirq/devices/superconducting_qubits_noise_properties.py +10 -9
- cirq/devices/thermal_noise_model.py +12 -12
- cirq/devices/unconstrained_device.py +3 -1
- cirq/experiments/n_qubit_tomography.py +15 -12
- cirq/experiments/qubit_characterizations.py +34 -39
- cirq/experiments/random_quantum_circuit_generation.py +38 -38
- cirq/experiments/random_quantum_circuit_generation_test.py +7 -4
- cirq/experiments/readout_confusion_matrix.py +17 -15
- cirq/experiments/single_qubit_readout_calibration.py +9 -5
- cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
- cirq/experiments/t1_decay_experiment.py +7 -5
- cirq/experiments/t2_decay_experiment.py +10 -7
- cirq/experiments/two_qubit_xeb.py +42 -43
- cirq/experiments/two_qubit_xeb_test.py +1 -1
- cirq/experiments/xeb_fitting.py +25 -21
- cirq/experiments/xeb_sampling.py +18 -14
- cirq/experiments/xeb_simulation.py +11 -7
- cirq/experiments/xeb_simulation_test.py +3 -3
- cirq/experiments/z_phase_calibration.py +27 -24
- cirq/experiments/z_phase_calibration_test.py +1 -4
- cirq/interop/quirk/cells/arithmetic_cells.py +11 -10
- cirq/interop/quirk/cells/cell.py +18 -15
- cirq/interop/quirk/cells/composite_cell.py +8 -8
- cirq/interop/quirk/cells/control_cells.py +14 -14
- cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
- cirq/interop/quirk/cells/input_cells.py +6 -4
- cirq/interop/quirk/cells/input_rotation_cells.py +14 -12
- cirq/interop/quirk/cells/measurement_cells.py +4 -1
- cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -1
- cirq/interop/quirk/cells/scalar_cells.py +4 -1
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
- cirq/interop/quirk/cells/swap_cell.py +7 -5
- cirq/interop/quirk/cells/testing.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +11 -8
- cirq/json_resolver_cache.py +5 -3
- cirq/linalg/decompositions.py +5 -4
- cirq/linalg/decompositions_test.py +1 -1
- cirq/linalg/operator_spaces.py +8 -8
- cirq/ops/arithmetic_operation.py +4 -2
- cirq/ops/boolean_hamiltonian.py +7 -6
- cirq/ops/classically_controlled_operation.py +23 -20
- cirq/ops/clifford_gate.py +43 -47
- cirq/ops/common_channels.py +16 -14
- cirq/ops/common_gates.py +49 -67
- cirq/ops/control_values.py +12 -15
- cirq/ops/controlled_gate.py +15 -17
- cirq/ops/controlled_operation.py +17 -15
- {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250418235304.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250418235304.dist-info}/RECORD +57 -57
- {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250418235304.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250418235304.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250418235304.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
from typing import Callable, Iterator, Sequence, Tuple, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
from cirq import ops, value
|
|
@@ -42,7 +44,7 @@ class QuirkQubitPermutationGate(ops.QubitPermutationGate):
|
|
|
42
44
|
def _value_equality_values_(self):
|
|
43
45
|
return self.identifier, self.name, self.permutation
|
|
44
46
|
|
|
45
|
-
def _circuit_diagram_info_(self, args:
|
|
47
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> Tuple[str, ...]:
|
|
46
48
|
return tuple(
|
|
47
49
|
f'{self.name}[{i}>{self.permutation[i]}]' for i in range(len(self.permutation))
|
|
48
50
|
)
|
|
@@ -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
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
from typing import Iterator, TYPE_CHECKING
|
|
15
18
|
|
|
16
19
|
from cirq import ops
|
|
@@ -28,5 +31,5 @@ def generate_all_scalar_cell_makers() -> Iterator[CellMaker]:
|
|
|
28
31
|
yield _scalar("√-i", ops.global_phase_operation((-1j) ** 0.5))
|
|
29
32
|
|
|
30
33
|
|
|
31
|
-
def _scalar(identifier: str, operation:
|
|
34
|
+
def _scalar(identifier: str, operation: cirq.Operation) -> CellMaker:
|
|
32
35
|
return CellMaker(identifier, size=1, maker=lambda _: operation)
|
|
@@ -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
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
from typing import Callable, Iterator, TYPE_CHECKING
|
|
15
18
|
|
|
16
19
|
import sympy
|
|
@@ -91,14 +94,14 @@ def generate_all_single_qubit_rotation_cell_makers() -> Iterator[CellMaker]:
|
|
|
91
94
|
yield _formula_gate("Rzft", "pi*t*t", ops.rz)
|
|
92
95
|
|
|
93
96
|
|
|
94
|
-
def _gate(identifier: str, gate:
|
|
97
|
+
def _gate(identifier: str, gate: cirq.Gate) -> CellMaker:
|
|
95
98
|
return CellMaker(
|
|
96
99
|
identifier=identifier, size=gate.num_qubits(), maker=lambda args: gate.on(*args.qubits)
|
|
97
100
|
)
|
|
98
101
|
|
|
99
102
|
|
|
100
103
|
def _formula_gate(
|
|
101
|
-
identifier: str, default_formula: str, gate_func: Callable[[
|
|
104
|
+
identifier: str, default_formula: str, gate_func: Callable[[cirq.TParamVal], cirq.Gate]
|
|
102
105
|
) -> CellMaker:
|
|
103
106
|
return CellMaker(
|
|
104
107
|
identifier=identifier,
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
from typing import Any, Iterable, Iterator, List, Optional, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
from cirq import ops, value
|
|
@@ -23,20 +25,20 @@ if TYPE_CHECKING:
|
|
|
23
25
|
|
|
24
26
|
@value.value_equality(unhashable=True)
|
|
25
27
|
class SwapCell(Cell):
|
|
26
|
-
def __init__(self, qubits: Iterable[
|
|
28
|
+
def __init__(self, qubits: Iterable[cirq.Qid], controls: Iterable[cirq.Qid]):
|
|
27
29
|
self._qubits = list(qubits)
|
|
28
30
|
self._controls = list(controls)
|
|
29
31
|
|
|
30
32
|
def gate_count(self) -> int:
|
|
31
33
|
return 1
|
|
32
34
|
|
|
33
|
-
def with_line_qubits_mapped_to(self, qubits: List[
|
|
35
|
+
def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
|
|
34
36
|
return SwapCell(
|
|
35
37
|
qubits=Cell._replace_qubits(self._qubits, qubits),
|
|
36
38
|
controls=Cell._replace_qubits(self._controls, qubits),
|
|
37
39
|
)
|
|
38
40
|
|
|
39
|
-
def modify_column(self, column: List[Optional[
|
|
41
|
+
def modify_column(self, column: List[Optional[Cell]]):
|
|
40
42
|
# Swallow other swap cells.
|
|
41
43
|
for i in range(len(column)):
|
|
42
44
|
gate = column[i]
|
|
@@ -45,12 +47,12 @@ class SwapCell(Cell):
|
|
|
45
47
|
self._qubits += gate._qubits
|
|
46
48
|
column[i] = None
|
|
47
49
|
|
|
48
|
-
def operations(self) ->
|
|
50
|
+
def operations(self) -> cirq.OP_TREE:
|
|
49
51
|
if len(self._qubits) != 2:
|
|
50
52
|
raise ValueError('Wrong number of swap gates in a column.')
|
|
51
53
|
return ops.SWAP(*self._qubits).controlled_by(*self._controls)
|
|
52
54
|
|
|
53
|
-
def controlled_by(self, qubit:
|
|
55
|
+
def controlled_by(self, qubit: cirq.Qid):
|
|
54
56
|
return SwapCell(self._qubits, self._controls + [qubit])
|
|
55
57
|
|
|
56
58
|
def _value_equality_values_(self) -> Any:
|
|
@@ -22,7 +22,7 @@ from cirq import quirk_url_to_circuit
|
|
|
22
22
|
|
|
23
23
|
def assert_url_to_circuit_returns(
|
|
24
24
|
json_text: str,
|
|
25
|
-
circuit: Optional[
|
|
25
|
+
circuit: Optional[cirq.Circuit] = None,
|
|
26
26
|
*,
|
|
27
27
|
unitary: Optional[np.ndarray] = None,
|
|
28
28
|
diagram: Optional[str] = None,
|
|
@@ -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
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
import json
|
|
15
18
|
import urllib.parse
|
|
16
19
|
from typing import (
|
|
@@ -47,12 +50,12 @@ if TYPE_CHECKING:
|
|
|
47
50
|
def quirk_url_to_circuit(
|
|
48
51
|
quirk_url: str,
|
|
49
52
|
*,
|
|
50
|
-
qubits: Optional[Sequence[
|
|
53
|
+
qubits: Optional[Sequence[cirq.Qid]] = None,
|
|
51
54
|
extra_cell_makers: Union[
|
|
52
|
-
Dict[str,
|
|
55
|
+
Dict[str, cirq.Gate], Iterable[cirq.interop.quirk.cells.CellMaker]
|
|
53
56
|
] = (),
|
|
54
57
|
max_operation_count: int = 10**6,
|
|
55
|
-
) ->
|
|
58
|
+
) -> cirq.Circuit:
|
|
56
59
|
"""Parses a Cirq circuit out of a Quirk URL.
|
|
57
60
|
|
|
58
61
|
Args:
|
|
@@ -150,13 +153,13 @@ def quirk_url_to_circuit(
|
|
|
150
153
|
def quirk_json_to_circuit(
|
|
151
154
|
data: dict,
|
|
152
155
|
*,
|
|
153
|
-
qubits: Optional[Sequence[
|
|
156
|
+
qubits: Optional[Sequence[cirq.Qid]] = None,
|
|
154
157
|
extra_cell_makers: Union[
|
|
155
|
-
Dict[str,
|
|
158
|
+
Dict[str, cirq.Gate], Iterable[cirq.interop.quirk.cells.CellMaker]
|
|
156
159
|
] = (),
|
|
157
160
|
quirk_url: Optional[str] = None,
|
|
158
161
|
max_operation_count: int = 10**6,
|
|
159
|
-
) ->
|
|
162
|
+
) -> cirq.Circuit:
|
|
160
163
|
"""Constructs a Cirq circuit from Quirk's JSON format.
|
|
161
164
|
|
|
162
165
|
Args:
|
|
@@ -239,7 +242,7 @@ def quirk_json_to_circuit(
|
|
|
239
242
|
if qubits is not None:
|
|
240
243
|
qs = qubits
|
|
241
244
|
|
|
242
|
-
def map_qubit(qubit:
|
|
245
|
+
def map_qubit(qubit: cirq.Qid) -> cirq.Qid:
|
|
243
246
|
q = cast(devices.LineQubit, qubit)
|
|
244
247
|
if q.x >= len(qs):
|
|
245
248
|
raise IndexError(
|
|
@@ -343,7 +346,7 @@ def _register_custom_gate(gate_json: Any, registry: Dict[str, CellMaker]):
|
|
|
343
346
|
)
|
|
344
347
|
|
|
345
348
|
|
|
346
|
-
def _init_ops(data: Dict[str, Any]) ->
|
|
349
|
+
def _init_ops(data: Dict[str, Any]) -> cirq.OP_TREE:
|
|
347
350
|
if 'init' not in data:
|
|
348
351
|
return []
|
|
349
352
|
init = data['init']
|
cirq/json_resolver_cache.py
CHANGED
|
@@ -12,16 +12,18 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""Methods for resolving JSON types during serialization."""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
15
18
|
import datetime
|
|
16
19
|
import functools
|
|
17
20
|
from typing import Dict, List, NamedTuple, Optional, Tuple, TYPE_CHECKING
|
|
18
21
|
|
|
19
|
-
from cirq.protocols.json_serialization import ObjectFactory
|
|
20
|
-
|
|
21
22
|
if TYPE_CHECKING:
|
|
22
23
|
import cirq
|
|
23
24
|
import cirq.devices.unconstrained_device
|
|
24
25
|
import cirq.ops.pauli_gates
|
|
26
|
+
from cirq.protocols.json_serialization import ObjectFactory
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
# Needed for backwards compatible named tuples of CrossEntropyResult
|
|
@@ -80,7 +82,7 @@ def _class_resolver_dictionary() -> Dict[str, ObjectFactory]:
|
|
|
80
82
|
)
|
|
81
83
|
|
|
82
84
|
def _cross_entropy_result_dict(
|
|
83
|
-
results: List[Tuple[List[
|
|
85
|
+
results: List[Tuple[List[cirq.Qid], CrossEntropyResult]], **kwargs
|
|
84
86
|
) -> CrossEntropyResultDict:
|
|
85
87
|
return CrossEntropyResultDict(results={tuple(qubits): result for qubits, result in results})
|
|
86
88
|
|
cirq/linalg/decompositions.py
CHANGED
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
"""Utility methods for breaking matrices into useful pieces."""
|
|
17
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
18
19
|
import cmath
|
|
19
20
|
import math
|
|
20
21
|
from typing import (
|
|
@@ -271,7 +272,7 @@ class AxisAngleDecomposition:
|
|
|
271
272
|
self.axis = tuple(axis)
|
|
272
273
|
self.angle = float(angle)
|
|
273
274
|
|
|
274
|
-
def canonicalize(self, atol: float = 1e-8) ->
|
|
275
|
+
def canonicalize(self, atol: float = 1e-8) -> AxisAngleDecomposition:
|
|
275
276
|
"""Returns a standardized AxisAngleDecomposition with the same unitary.
|
|
276
277
|
|
|
277
278
|
Ensures the axis (x, y, z) satisfies x+y+z >= 0.
|
|
@@ -524,7 +525,7 @@ class KakDecomposition:
|
|
|
524
525
|
|
|
525
526
|
|
|
526
527
|
def scatter_plot_normalized_kak_interaction_coefficients(
|
|
527
|
-
interactions: Iterable[Union[np.ndarray,
|
|
528
|
+
interactions: Iterable[Union[np.ndarray, cirq.SupportsUnitary, KakDecomposition]],
|
|
528
529
|
*,
|
|
529
530
|
include_frame: bool = True,
|
|
530
531
|
ax: Optional[mplot3d.axes3d.Axes3D] = None,
|
|
@@ -786,7 +787,7 @@ KAK_GAMMA = np.array([[1, 1, 1, 1],
|
|
|
786
787
|
|
|
787
788
|
def kak_decomposition(
|
|
788
789
|
unitary_object: Union[
|
|
789
|
-
np.ndarray,
|
|
790
|
+
np.ndarray, cirq.SupportsUnitary, cirq.Gate, cirq.Operation, KakDecomposition
|
|
790
791
|
],
|
|
791
792
|
*,
|
|
792
793
|
rtol: float = 1e-5,
|
|
@@ -582,7 +582,7 @@ def _local_two_qubit_unitaries(samples, random_state):
|
|
|
582
582
|
_kak_gens = np.array([np.kron(X, X), np.kron(Y, Y), np.kron(Z, Z)])
|
|
583
583
|
|
|
584
584
|
|
|
585
|
-
def _random_two_qubit_unitaries(num_samples: int, random_state:
|
|
585
|
+
def _random_two_qubit_unitaries(num_samples: int, random_state: cirq.RANDOM_STATE_OR_SEED_LIKE):
|
|
586
586
|
# Randomly generated two-qubit unitaries and the KAK vectors (not canonical)
|
|
587
587
|
kl = _local_two_qubit_unitaries(num_samples, random_state)
|
|
588
588
|
|
cirq/linalg/operator_spaces.py
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Utilities for manipulating linear operators as elements of vector space."""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
from typing import Dict, Tuple, TYPE_CHECKING
|
|
17
20
|
|
|
18
21
|
import numpy as np
|
|
@@ -82,16 +85,13 @@ def matrix_from_basis_coefficients(
|
|
|
82
85
|
|
|
83
86
|
|
|
84
87
|
def pow_pauli_combination(
|
|
85
|
-
ai:
|
|
86
|
-
ax:
|
|
87
|
-
ay:
|
|
88
|
-
az:
|
|
88
|
+
ai: cirq.TParamValComplex,
|
|
89
|
+
ax: cirq.TParamValComplex,
|
|
90
|
+
ay: cirq.TParamValComplex,
|
|
91
|
+
az: cirq.TParamValComplex,
|
|
89
92
|
exponent: int,
|
|
90
93
|
) -> Tuple[
|
|
91
|
-
|
|
92
|
-
'cirq.TParamValComplex',
|
|
93
|
-
'cirq.TParamValComplex',
|
|
94
|
-
'cirq.TParamValComplex',
|
|
94
|
+
cirq.TParamValComplex, cirq.TParamValComplex, cirq.TParamValComplex, cirq.TParamValComplex
|
|
95
95
|
]:
|
|
96
96
|
"""Computes non-negative integer power of single-qubit Pauli combination.
|
|
97
97
|
|
cirq/ops/arithmetic_operation.py
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""Helper class for implementing classical arithmetic operations."""
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
import abc
|
|
17
19
|
import itertools
|
|
18
20
|
from typing import cast, Iterable, List, Sequence, Tuple, TYPE_CHECKING, Union
|
|
@@ -170,7 +172,7 @@ class ArithmeticGate(Gate, metaclass=abc.ABCMeta):
|
|
|
170
172
|
shape.append(i)
|
|
171
173
|
return tuple(shape)
|
|
172
174
|
|
|
173
|
-
def _apply_unitary_(self, args:
|
|
175
|
+
def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs):
|
|
174
176
|
registers = self.registers()
|
|
175
177
|
input_ranges: List[Sequence[int]] = []
|
|
176
178
|
shape: List[int] = []
|
|
@@ -231,7 +233,7 @@ class ArithmeticGate(Gate, metaclass=abc.ABCMeta):
|
|
|
231
233
|
|
|
232
234
|
|
|
233
235
|
def _describe_bad_arithmetic_changed_const(
|
|
234
|
-
registers: Sequence[Union[int, Sequence[Union[
|
|
236
|
+
registers: Sequence[Union[int, Sequence[Union[cirq.Qid, int]]]],
|
|
235
237
|
inputs: List[int],
|
|
236
238
|
outputs: List[int],
|
|
237
239
|
) -> str:
|
cirq/ops/boolean_hamiltonian.py
CHANGED
|
@@ -22,6 +22,9 @@ References:
|
|
|
22
22
|
[4] Efficient Quantum Circuits for Diagonal Unitaries Without Ancillas by Jonathan Welch, Daniel
|
|
23
23
|
Greenbaum, Sarah Mostame, and Alán Aspuru-Guzik, https://arxiv.org/abs/1306.3991
|
|
24
24
|
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
25
28
|
import functools
|
|
26
29
|
import itertools
|
|
27
30
|
from typing import Any, Dict, Generator, List, Sequence, Tuple
|
|
@@ -93,10 +96,10 @@ class BooleanHamiltonianGate(raw_types.Gate):
|
|
|
93
96
|
@classmethod
|
|
94
97
|
def _from_json_dict_(
|
|
95
98
|
cls, parameter_names, boolean_strs, theta, **kwargs
|
|
96
|
-
) ->
|
|
99
|
+
) -> cirq.BooleanHamiltonianGate:
|
|
97
100
|
return cls(parameter_names, boolean_strs, theta)
|
|
98
101
|
|
|
99
|
-
def _decompose_(self, qubits: Sequence[
|
|
102
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
|
|
100
103
|
qubit_map = dict(zip(self._parameter_names, qubits))
|
|
101
104
|
boolean_exprs = [sympy_parser.parse_expr(boolean_str) for boolean_str in self._boolean_strs]
|
|
102
105
|
hamiltonian_polynomial_list = [
|
|
@@ -299,10 +302,8 @@ def _simplify_cnots(cnots: List[Tuple[int, int]]) -> List[Tuple[int, int]]:
|
|
|
299
302
|
|
|
300
303
|
|
|
301
304
|
def _get_gates_from_hamiltonians(
|
|
302
|
-
hamiltonian_polynomial_list: List[
|
|
303
|
-
|
|
304
|
-
theta: float,
|
|
305
|
-
) -> Generator['cirq.Operation', None, None]:
|
|
305
|
+
hamiltonian_polynomial_list: List[cirq.PauliSum], qubit_map: Dict[str, cirq.Qid], theta: float
|
|
306
|
+
) -> Generator[cirq.Operation, None, None]:
|
|
306
307
|
"""Builds a circuit according to [1].
|
|
307
308
|
|
|
308
309
|
Args:
|
|
@@ -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
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
from typing import (
|
|
15
18
|
AbstractSet,
|
|
16
19
|
Any,
|
|
@@ -79,8 +82,8 @@ class ClassicallyControlledOperation(raw_types.Operation):
|
|
|
79
82
|
|
|
80
83
|
def __init__(
|
|
81
84
|
self,
|
|
82
|
-
sub_operation:
|
|
83
|
-
conditions: Sequence[Union[str,
|
|
85
|
+
sub_operation: cirq.Operation,
|
|
86
|
+
conditions: Sequence[Union[str, cirq.MeasurementKey, cirq.Condition, sympy.Basic]],
|
|
84
87
|
):
|
|
85
88
|
"""Initializes a `ClassicallyControlledOperation`.
|
|
86
89
|
|
|
@@ -106,7 +109,7 @@ class ClassicallyControlledOperation(raw_types.Operation):
|
|
|
106
109
|
if isinstance(sub_operation, ClassicallyControlledOperation):
|
|
107
110
|
conditions += sub_operation._conditions
|
|
108
111
|
sub_operation = sub_operation._sub_operation
|
|
109
|
-
conds: List[
|
|
112
|
+
conds: List[cirq.Condition] = []
|
|
110
113
|
for c in conditions:
|
|
111
114
|
if isinstance(c, str):
|
|
112
115
|
c = value.MeasurementKey.parse_serialized(c)
|
|
@@ -115,14 +118,14 @@ class ClassicallyControlledOperation(raw_types.Operation):
|
|
|
115
118
|
if isinstance(c, sympy.Basic):
|
|
116
119
|
c = value.SympyCondition(c)
|
|
117
120
|
conds.append(c)
|
|
118
|
-
self._conditions: Tuple[
|
|
119
|
-
self._sub_operation:
|
|
121
|
+
self._conditions: Tuple[cirq.Condition, ...] = tuple(conds)
|
|
122
|
+
self._sub_operation: cirq.Operation = sub_operation
|
|
120
123
|
|
|
121
124
|
@property
|
|
122
|
-
def classical_controls(self) -> FrozenSet[
|
|
125
|
+
def classical_controls(self) -> FrozenSet[cirq.Condition]:
|
|
123
126
|
return frozenset(self._conditions).union(self._sub_operation.classical_controls)
|
|
124
127
|
|
|
125
|
-
def without_classical_controls(self) ->
|
|
128
|
+
def without_classical_controls(self) -> cirq.Operation:
|
|
126
129
|
return self._sub_operation.without_classical_controls()
|
|
127
130
|
|
|
128
131
|
@property
|
|
@@ -137,7 +140,7 @@ class ClassicallyControlledOperation(raw_types.Operation):
|
|
|
137
140
|
def _decompose_(self):
|
|
138
141
|
return self._decompose_with_context_()
|
|
139
142
|
|
|
140
|
-
def _decompose_with_context_(self, context: Optional[
|
|
143
|
+
def _decompose_with_context_(self, context: Optional[cirq.DecompositionContext] = None):
|
|
141
144
|
result = protocols.decompose_once(
|
|
142
145
|
self._sub_operation, NotImplemented, flatten=False, context=context
|
|
143
146
|
)
|
|
@@ -168,14 +171,14 @@ class ClassicallyControlledOperation(raw_types.Operation):
|
|
|
168
171
|
return protocols.parameter_names(self._sub_operation)
|
|
169
172
|
|
|
170
173
|
def _resolve_parameters_(
|
|
171
|
-
self, resolver:
|
|
172
|
-
) ->
|
|
174
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
175
|
+
) -> ClassicallyControlledOperation:
|
|
173
176
|
new_sub_op = protocols.resolve_parameters(self._sub_operation, resolver, recursive)
|
|
174
177
|
return ClassicallyControlledOperation(new_sub_op, self._conditions)
|
|
175
178
|
|
|
176
179
|
def _circuit_diagram_info_(
|
|
177
|
-
self, args:
|
|
178
|
-
) -> Optional[
|
|
180
|
+
self, args: cirq.CircuitDiagramInfoArgs
|
|
181
|
+
) -> Optional[protocols.CircuitDiagramInfo]:
|
|
179
182
|
sub_args = protocols.CircuitDiagramInfoArgs(
|
|
180
183
|
known_qubit_count=args.known_qubit_count,
|
|
181
184
|
known_qubits=args.known_qubits,
|
|
@@ -210,39 +213,39 @@ class ClassicallyControlledOperation(raw_types.Operation):
|
|
|
210
213
|
def _json_dict_(self) -> Dict[str, Any]:
|
|
211
214
|
return {'conditions': self._conditions, 'sub_operation': self._sub_operation}
|
|
212
215
|
|
|
213
|
-
def _act_on_(self, sim_state:
|
|
216
|
+
def _act_on_(self, sim_state: cirq.SimulationStateBase) -> bool:
|
|
214
217
|
if all(c.resolve(sim_state.classical_data) for c in self._conditions):
|
|
215
218
|
protocols.act_on(self._sub_operation, sim_state)
|
|
216
219
|
return True
|
|
217
220
|
|
|
218
221
|
def _with_measurement_key_mapping_(
|
|
219
222
|
self, key_map: Mapping[str, str]
|
|
220
|
-
) ->
|
|
223
|
+
) -> ClassicallyControlledOperation:
|
|
221
224
|
conditions = [protocols.with_measurement_key_mapping(c, key_map) for c in self._conditions]
|
|
222
225
|
sub_operation = protocols.with_measurement_key_mapping(self._sub_operation, key_map)
|
|
223
226
|
sub_operation = self._sub_operation if sub_operation is NotImplemented else sub_operation
|
|
224
227
|
return sub_operation.with_classical_controls(*conditions)
|
|
225
228
|
|
|
226
|
-
def _with_key_path_prefix_(self, prefix: Tuple[str, ...]) ->
|
|
229
|
+
def _with_key_path_prefix_(self, prefix: Tuple[str, ...]) -> ClassicallyControlledOperation:
|
|
227
230
|
conditions = [protocols.with_key_path_prefix(c, prefix) for c in self._conditions]
|
|
228
231
|
sub_operation = protocols.with_key_path_prefix(self._sub_operation, prefix)
|
|
229
232
|
sub_operation = self._sub_operation if sub_operation is NotImplemented else sub_operation
|
|
230
233
|
return sub_operation.with_classical_controls(*conditions)
|
|
231
234
|
|
|
232
235
|
def _with_rescoped_keys_(
|
|
233
|
-
self, path: Tuple[str, ...], bindable_keys: FrozenSet[
|
|
234
|
-
) ->
|
|
236
|
+
self, path: Tuple[str, ...], bindable_keys: FrozenSet[cirq.MeasurementKey]
|
|
237
|
+
) -> ClassicallyControlledOperation:
|
|
235
238
|
conds = [protocols.with_rescoped_keys(c, path, bindable_keys) for c in self._conditions]
|
|
236
239
|
sub_operation = protocols.with_rescoped_keys(self._sub_operation, path, bindable_keys)
|
|
237
240
|
return sub_operation.with_classical_controls(*conds)
|
|
238
241
|
|
|
239
|
-
def _control_keys_(self) -> FrozenSet[
|
|
240
|
-
local_keys: FrozenSet[
|
|
242
|
+
def _control_keys_(self) -> FrozenSet[cirq.MeasurementKey]:
|
|
243
|
+
local_keys: FrozenSet[cirq.MeasurementKey] = frozenset(
|
|
241
244
|
k for condition in self._conditions for k in condition.keys
|
|
242
245
|
)
|
|
243
246
|
return local_keys.union(protocols.control_keys(self._sub_operation))
|
|
244
247
|
|
|
245
|
-
def _qasm_(self, args:
|
|
248
|
+
def _qasm_(self, args: cirq.QasmArgs) -> Optional[str]:
|
|
246
249
|
args.validate_version('2.0', '3.0')
|
|
247
250
|
if len(self._conditions) > 1:
|
|
248
251
|
raise ValueError('QASM does not support multiple conditions.')
|