cirq-core 1.6.0.dev20250424231143__py3-none-any.whl → 1.6.0.dev20250428201230__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/ops/dense_pauli_string.py +28 -28
- cirq/ops/diagonal_gate.py +12 -14
- cirq/ops/eigen_gate.py +8 -5
- cirq/ops/fourier_transform.py +8 -12
- cirq/ops/fsim_gate.py +38 -37
- cirq/ops/gate_operation.py +25 -27
- cirq/ops/gateset.py +7 -5
- cirq/ops/global_phase_op.py +11 -11
- cirq/ops/greedy_qubit_manager.py +9 -7
- cirq/ops/identity.py +8 -6
- cirq/ops/kraus_channel.py +7 -4
- cirq/ops/linear_combinations.py +36 -34
- cirq/ops/matrix_gates.py +10 -10
- cirq/ops/measure_util.py +6 -4
- cirq/ops/measurement_gate.py +12 -12
- cirq/ops/mixed_unitary_channel.py +7 -4
- cirq/ops/named_qubit.py +8 -5
- cirq/ops/op_tree.py +4 -2
- cirq/ops/parallel_gate.py +11 -13
- cirq/ops/parity_gates.py +15 -17
- cirq/ops/pauli_gates.py +20 -17
- cirq/ops/pauli_interaction_gate.py +10 -14
- cirq/ops/pauli_measurement_gate.py +20 -20
- cirq/ops/pauli_string.py +76 -79
- cirq/ops/pauli_string_phasor.py +30 -30
- cirq/ops/pauli_string_raw_types.py +6 -4
- cirq/ops/pauli_sum_exponential.py +11 -11
- cirq/ops/permutation_gate.py +5 -3
- cirq/ops/phased_iswap_gate.py +8 -8
- cirq/ops/phased_x_gate.py +8 -9
- cirq/ops/phased_x_z_gate.py +15 -13
- cirq/ops/qid_util.py +6 -4
- cirq/ops/qubit_manager.py +9 -7
- cirq/ops/random_gate_channel.py +9 -7
- cirq/ops/raw_types.py +70 -72
- cirq/ops/raw_types_test.py +10 -6
- cirq/ops/state_preparation_channel.py +4 -4
- cirq/ops/swap_gates.py +7 -9
- cirq/ops/three_qubit_gates.py +22 -28
- cirq/ops/two_qubit_diagonal_gate.py +8 -8
- cirq/ops/uniform_superposition_gate.py +3 -1
- cirq/ops/wait_gate.py +12 -9
- cirq/protocols/act_on_protocol.py +6 -4
- cirq/protocols/act_on_protocol_test.py +8 -5
- cirq/protocols/apply_unitary_protocol.py +10 -8
- cirq/protocols/circuit_diagram_info_protocol.py +10 -8
- cirq/protocols/control_key_protocol.py +5 -3
- cirq/protocols/decompose_protocol.py +28 -24
- cirq/protocols/decompose_protocol_test.py +5 -2
- cirq/protocols/inverse_protocol.py +10 -8
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/RECORD +57 -57
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/WHEEL +1 -1
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/top_level.txt +0 -0
cirq/ops/pauli_string_phasor.py
CHANGED
|
@@ -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
|
import numbers
|
|
16
18
|
from typing import (
|
|
17
19
|
AbstractSet,
|
|
@@ -63,10 +65,10 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
63
65
|
def __init__(
|
|
64
66
|
self,
|
|
65
67
|
pauli_string: ps.PauliString,
|
|
66
|
-
qubits: Optional[Sequence[
|
|
68
|
+
qubits: Optional[Sequence[cirq.Qid]] = None,
|
|
67
69
|
*,
|
|
68
|
-
exponent_neg:
|
|
69
|
-
exponent_pos:
|
|
70
|
+
exponent_neg: cirq.TParamVal = 1,
|
|
71
|
+
exponent_pos: cirq.TParamVal = 0,
|
|
70
72
|
) -> None:
|
|
71
73
|
"""Initializes the operation.
|
|
72
74
|
|
|
@@ -106,34 +108,34 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
106
108
|
self._pauli_string = gate.dense_pauli_string.on(*self.qubits)
|
|
107
109
|
|
|
108
110
|
@property
|
|
109
|
-
def gate(self) ->
|
|
111
|
+
def gate(self) -> cirq.PauliStringPhasorGate:
|
|
110
112
|
"""The gate applied by the operation."""
|
|
111
113
|
return cast(PauliStringPhasorGate, self._gate)
|
|
112
114
|
|
|
113
115
|
@property
|
|
114
|
-
def exponent_neg(self) ->
|
|
116
|
+
def exponent_neg(self) -> cirq.TParamVal:
|
|
115
117
|
"""The negative exponent."""
|
|
116
118
|
return self.gate.exponent_neg
|
|
117
119
|
|
|
118
120
|
@property
|
|
119
|
-
def exponent_pos(self) ->
|
|
121
|
+
def exponent_pos(self) -> cirq.TParamVal:
|
|
120
122
|
"""The positive exponent."""
|
|
121
123
|
return self.gate.exponent_pos
|
|
122
124
|
|
|
123
125
|
@property
|
|
124
|
-
def pauli_string(self) ->
|
|
126
|
+
def pauli_string(self) -> cirq.PauliString:
|
|
125
127
|
"""The underlying pauli string."""
|
|
126
128
|
return self._pauli_string
|
|
127
129
|
|
|
128
130
|
@property
|
|
129
|
-
def exponent_relative(self) ->
|
|
131
|
+
def exponent_relative(self) -> cirq.TParamVal:
|
|
130
132
|
"""The relative exponent between negative and positive exponents."""
|
|
131
133
|
return self.gate.exponent_relative
|
|
132
134
|
|
|
133
135
|
def _value_equality_values_(self):
|
|
134
136
|
return (self.pauli_string, self.qubits, self.exponent_neg, self.exponent_pos)
|
|
135
137
|
|
|
136
|
-
def equal_up_to_global_phase(self, other:
|
|
138
|
+
def equal_up_to_global_phase(self, other: PauliStringPhasor) -> bool:
|
|
137
139
|
"""Checks equality of two PauliStringPhasors, up to global phase."""
|
|
138
140
|
if isinstance(other, PauliStringPhasor):
|
|
139
141
|
return (
|
|
@@ -143,7 +145,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
143
145
|
)
|
|
144
146
|
return False
|
|
145
147
|
|
|
146
|
-
def map_qubits(self, qubit_map: Dict[raw_types.Qid, raw_types.Qid]) ->
|
|
148
|
+
def map_qubits(self, qubit_map: Dict[raw_types.Qid, raw_types.Qid]) -> PauliStringPhasor:
|
|
147
149
|
"""Maps the qubits inside the PauliStringPhasor.
|
|
148
150
|
|
|
149
151
|
Args:
|
|
@@ -168,13 +170,13 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
168
170
|
exponent_pos=self.exponent_pos,
|
|
169
171
|
)
|
|
170
172
|
|
|
171
|
-
def can_merge_with(self, op:
|
|
173
|
+
def can_merge_with(self, op: PauliStringPhasor) -> bool:
|
|
172
174
|
"""Checks whether the underlying PauliStrings can be merged."""
|
|
173
175
|
return (
|
|
174
176
|
self.pauli_string.equal_up_to_coefficient(op.pauli_string) and self.qubits == op.qubits
|
|
175
177
|
)
|
|
176
178
|
|
|
177
|
-
def merged_with(self, op:
|
|
179
|
+
def merged_with(self, op: PauliStringPhasor) -> PauliStringPhasor:
|
|
178
180
|
"""Merges two PauliStringPhasors."""
|
|
179
181
|
if not self.can_merge_with(op):
|
|
180
182
|
raise ValueError(f'Cannot merge operations: {self}, {op}')
|
|
@@ -184,9 +186,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
184
186
|
self.pauli_string, qubits=self.qubits, exponent_pos=pp, exponent_neg=pn
|
|
185
187
|
)
|
|
186
188
|
|
|
187
|
-
def _circuit_diagram_info_(
|
|
188
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
189
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
189
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
190
190
|
qubits = self.qubits if args.known_qubits is None else args.known_qubits
|
|
191
191
|
if not qubits:
|
|
192
192
|
return NotImplemented
|
|
@@ -201,7 +201,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
201
201
|
|
|
202
202
|
def pass_operations_over(
|
|
203
203
|
self, ops: Iterable[raw_types.Operation], after_to_before: bool = False
|
|
204
|
-
) ->
|
|
204
|
+
) -> PauliStringPhasor:
|
|
205
205
|
"""Determines how the Pauli phasor changes when conjugated by Cliffords.
|
|
206
206
|
|
|
207
207
|
The output and input pauli phasors are related by a circuit equivalence.
|
|
@@ -277,8 +277,8 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
277
277
|
self,
|
|
278
278
|
dense_pauli_string: dps.DensePauliString,
|
|
279
279
|
*,
|
|
280
|
-
exponent_neg:
|
|
281
|
-
exponent_pos:
|
|
280
|
+
exponent_neg: cirq.TParamVal = 1,
|
|
281
|
+
exponent_pos: cirq.TParamVal = 0,
|
|
282
282
|
) -> None:
|
|
283
283
|
"""Initializes the PauliStringPhasorGate.
|
|
284
284
|
|
|
@@ -308,29 +308,29 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
308
308
|
self._exponent_pos = value.canonicalize_half_turns(exponent_pos)
|
|
309
309
|
|
|
310
310
|
@property
|
|
311
|
-
def exponent_relative(self) ->
|
|
311
|
+
def exponent_relative(self) -> cirq.TParamVal:
|
|
312
312
|
"""The relative exponent between negative and positive exponents."""
|
|
313
313
|
return value.canonicalize_half_turns(self.exponent_neg - self.exponent_pos)
|
|
314
314
|
|
|
315
315
|
@property
|
|
316
|
-
def exponent_neg(self) ->
|
|
316
|
+
def exponent_neg(self) -> cirq.TParamVal:
|
|
317
317
|
"""The negative exponent."""
|
|
318
318
|
return self._exponent_neg
|
|
319
319
|
|
|
320
320
|
@property
|
|
321
|
-
def exponent_pos(self) ->
|
|
321
|
+
def exponent_pos(self) -> cirq.TParamVal:
|
|
322
322
|
"""The positive exponent."""
|
|
323
323
|
return self._exponent_pos
|
|
324
324
|
|
|
325
325
|
@property
|
|
326
|
-
def dense_pauli_string(self) ->
|
|
326
|
+
def dense_pauli_string(self) -> cirq.DensePauliString:
|
|
327
327
|
"""The underlying DensePauliString."""
|
|
328
328
|
return self._dense_pauli_string
|
|
329
329
|
|
|
330
330
|
def _value_equality_values_(self):
|
|
331
331
|
return (self.dense_pauli_string, self.exponent_neg, self.exponent_pos)
|
|
332
332
|
|
|
333
|
-
def equal_up_to_global_phase(self, other:
|
|
333
|
+
def equal_up_to_global_phase(self, other: cirq.PauliStringPhasorGate) -> bool:
|
|
334
334
|
"""Checks equality of two PauliStringPhasors, up to global phase."""
|
|
335
335
|
if isinstance(other, PauliStringPhasorGate):
|
|
336
336
|
rel1 = self.exponent_relative
|
|
@@ -338,7 +338,7 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
338
338
|
return rel1 == rel2 and self.dense_pauli_string == other.dense_pauli_string
|
|
339
339
|
return False
|
|
340
340
|
|
|
341
|
-
def __pow__(self, exponent: Union[float, sympy.Symbol]) ->
|
|
341
|
+
def __pow__(self, exponent: Union[float, sympy.Symbol]) -> PauliStringPhasorGate:
|
|
342
342
|
pn = protocols.mul(self.exponent_neg, exponent, None)
|
|
343
343
|
pp = protocols.mul(self.exponent_pos, exponent, None)
|
|
344
344
|
if pn is None or pp is None:
|
|
@@ -348,11 +348,11 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
348
348
|
def _has_unitary_(self) -> bool:
|
|
349
349
|
return not self._is_parameterized_()
|
|
350
350
|
|
|
351
|
-
def _to_z_basis_ops(self, qubits: Sequence[
|
|
351
|
+
def _to_z_basis_ops(self, qubits: Sequence[cirq.Qid]) -> Iterator[raw_types.Operation]:
|
|
352
352
|
"""Returns operations to convert the qubits to the computational basis."""
|
|
353
353
|
return self.dense_pauli_string.on(*qubits).to_z_basis_ops()
|
|
354
354
|
|
|
355
|
-
def _decompose_(self, qubits: Sequence[
|
|
355
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
356
356
|
if len(self.dense_pauli_string) <= 0:
|
|
357
357
|
return
|
|
358
358
|
any_qubit = qubits[0]
|
|
@@ -387,8 +387,8 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
387
387
|
)
|
|
388
388
|
|
|
389
389
|
def _resolve_parameters_(
|
|
390
|
-
self, resolver:
|
|
391
|
-
) ->
|
|
390
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
391
|
+
) -> PauliStringPhasorGate:
|
|
392
392
|
exponent_neg = resolver.value_of(self.exponent_neg, recursive)
|
|
393
393
|
exponent_pos = resolver.value_of(self.exponent_pos, recursive)
|
|
394
394
|
if isinstance(exponent_neg, numbers.Complex):
|
|
@@ -427,7 +427,7 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
427
427
|
"""The number of qubits for the gate."""
|
|
428
428
|
return len(self.dense_pauli_string)
|
|
429
429
|
|
|
430
|
-
def on(self, *qubits:
|
|
430
|
+
def on(self, *qubits: cirq.Qid) -> cirq.PauliStringPhasor:
|
|
431
431
|
"""Creates a PauliStringPhasor on the qubits."""
|
|
432
432
|
return PauliStringPhasor(
|
|
433
433
|
self.dense_pauli_string.on(*qubits),
|
|
@@ -443,7 +443,7 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
443
443
|
|
|
444
444
|
|
|
445
445
|
def xor_nonlocal_decompose(
|
|
446
|
-
qubits: Iterable[raw_types.Qid], onto_qubit:
|
|
446
|
+
qubits: Iterable[raw_types.Qid], onto_qubit: cirq.Qid
|
|
447
447
|
) -> Iterable[raw_types.Operation]:
|
|
448
448
|
"""Decomposition ignores connectivity."""
|
|
449
449
|
for qubit in qubits:
|
|
@@ -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
|
import abc
|
|
16
18
|
from typing import Any, Dict, Sequence, Tuple, TYPE_CHECKING
|
|
17
19
|
|
|
@@ -29,14 +31,14 @@ class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta):
|
|
|
29
31
|
self._pauli_string = pauli_string
|
|
30
32
|
|
|
31
33
|
@property
|
|
32
|
-
def pauli_string(self) ->
|
|
34
|
+
def pauli_string(self) -> cirq.PauliString:
|
|
33
35
|
return self._pauli_string
|
|
34
36
|
|
|
35
37
|
def validate_args(self, qubits: Sequence[raw_types.Qid]) -> None:
|
|
36
38
|
if len(qubits) != len(self.pauli_string):
|
|
37
39
|
raise ValueError('Incorrect number of qubits for gate')
|
|
38
40
|
|
|
39
|
-
def with_qubits(self, *new_qubits:
|
|
41
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> Self:
|
|
40
42
|
self.validate_args(new_qubits)
|
|
41
43
|
return self.map_qubits(dict(zip(self.pauli_string.qubits, new_qubits)))
|
|
42
44
|
|
|
@@ -53,8 +55,8 @@ class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta):
|
|
|
53
55
|
return tuple(self.pauli_string)
|
|
54
56
|
|
|
55
57
|
def _pauli_string_diagram_info(
|
|
56
|
-
self, args:
|
|
57
|
-
) ->
|
|
58
|
+
self, args: protocols.CircuitDiagramInfoArgs, exponent: Any = 1
|
|
59
|
+
) -> cirq.CircuitDiagramInfo:
|
|
58
60
|
qubits = self.qubits if args.known_qubits is None else args.known_qubits
|
|
59
61
|
syms = tuple(f'[{self.pauli_string[qubit]}]' for qubit in qubits)
|
|
60
62
|
return protocols.CircuitDiagramInfo(wire_symbols=syms, exponent=exponent)
|
|
@@ -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 Any, Iterator, Tuple, TYPE_CHECKING
|
|
15
18
|
|
|
16
19
|
import numpy as np
|
|
@@ -22,7 +25,7 @@ if TYPE_CHECKING:
|
|
|
22
25
|
import cirq
|
|
23
26
|
|
|
24
27
|
|
|
25
|
-
def _all_pauli_strings_commute(pauli_sum:
|
|
28
|
+
def _all_pauli_strings_commute(pauli_sum: cirq.PauliSum) -> bool:
|
|
26
29
|
for x in pauli_sum:
|
|
27
30
|
for y in pauli_sum:
|
|
28
31
|
if not protocols.commutes(x, y):
|
|
@@ -42,10 +45,7 @@ class PauliSumExponential:
|
|
|
42
45
|
"""
|
|
43
46
|
|
|
44
47
|
def __init__(
|
|
45
|
-
self,
|
|
46
|
-
pauli_sum_like: 'cirq.PauliSumLike',
|
|
47
|
-
exponent: 'cirq.TParamVal' = 1,
|
|
48
|
-
atol: float = 1e-8,
|
|
48
|
+
self, pauli_sum_like: cirq.PauliSumLike, exponent: cirq.TParamVal = 1, atol: float = 1e-8
|
|
49
49
|
):
|
|
50
50
|
pauli_sum = linear_combinations.PauliSum.wrap(pauli_sum_like)
|
|
51
51
|
if not _all_pauli_strings_commute(pauli_sum):
|
|
@@ -68,13 +68,13 @@ class PauliSumExponential:
|
|
|
68
68
|
self._pauli_sum = pauli_sum
|
|
69
69
|
|
|
70
70
|
@property
|
|
71
|
-
def qubits(self) -> Tuple[
|
|
71
|
+
def qubits(self) -> Tuple[cirq.Qid, ...]:
|
|
72
72
|
return self._pauli_sum.qubits
|
|
73
73
|
|
|
74
74
|
def _value_equality_values_(self) -> Any:
|
|
75
75
|
return (self._pauli_sum, self._exponent)
|
|
76
76
|
|
|
77
|
-
def with_qubits(self, *new_qubits:
|
|
77
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> PauliSumExponential:
|
|
78
78
|
return PauliSumExponential(self._pauli_sum.with_qubits(*new_qubits), self._exponent)
|
|
79
79
|
|
|
80
80
|
@_compat.cached_method
|
|
@@ -82,14 +82,14 @@ class PauliSumExponential:
|
|
|
82
82
|
return protocols.is_parameterized(self._exponent)
|
|
83
83
|
|
|
84
84
|
def _resolve_parameters_(
|
|
85
|
-
self, resolver:
|
|
86
|
-
) ->
|
|
85
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
86
|
+
) -> PauliSumExponential:
|
|
87
87
|
return PauliSumExponential(
|
|
88
88
|
self._pauli_sum,
|
|
89
89
|
exponent=protocols.resolve_parameters(self._exponent, resolver, recursive),
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
def __iter__(self) -> Iterator[
|
|
92
|
+
def __iter__(self) -> Iterator[cirq.PauliStringPhasor]:
|
|
93
93
|
for pauli_string in self._pauli_sum:
|
|
94
94
|
theta = pauli_string.coefficient * self._multiplier
|
|
95
95
|
theta *= self._exponent / np.pi
|
|
@@ -119,7 +119,7 @@ class PauliSumExponential:
|
|
|
119
119
|
def _unitary_(self) -> np.ndarray:
|
|
120
120
|
return self.matrix()
|
|
121
121
|
|
|
122
|
-
def __pow__(self, exponent: int) ->
|
|
122
|
+
def __pow__(self, exponent: int) -> PauliSumExponential:
|
|
123
123
|
return PauliSumExponential(self._pauli_sum, self._exponent * exponent)
|
|
124
124
|
|
|
125
125
|
def __repr__(self) -> str:
|
cirq/ops/permutation_gate.py
CHANGED
|
@@ -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, Dict, Iterator, Sequence, Tuple, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
from cirq import protocols, value
|
|
@@ -73,7 +75,7 @@ class QubitPermutationGate(raw_types.Gate):
|
|
|
73
75
|
def _has_unitary_(self):
|
|
74
76
|
return True
|
|
75
77
|
|
|
76
|
-
def _decompose_(self, qubits: Sequence[
|
|
78
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
77
79
|
permutation = [p for p in self.permutation]
|
|
78
80
|
|
|
79
81
|
for i in range(len(permutation)):
|
|
@@ -90,7 +92,7 @@ class QubitPermutationGate(raw_types.Gate):
|
|
|
90
92
|
for idx in cycle[1:]:
|
|
91
93
|
yield swap_gates.SWAP(qubits[cycle[0]], qubits[idx])
|
|
92
94
|
|
|
93
|
-
def _apply_unitary_(self, args:
|
|
95
|
+
def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs):
|
|
94
96
|
# Compute the permutation index list.
|
|
95
97
|
permuted_axes = list(range(len(args.target_tensor.shape)))
|
|
96
98
|
for i in range(len(args.axes)):
|
|
@@ -104,7 +106,7 @@ class QubitPermutationGate(raw_types.Gate):
|
|
|
104
106
|
args.available_buffer[...] = args.target_tensor.transpose(permuted_axes)
|
|
105
107
|
return args.available_buffer
|
|
106
108
|
|
|
107
|
-
def _circuit_diagram_info_(self, args:
|
|
109
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> Tuple[str, ...]:
|
|
108
110
|
return tuple(f'[{i}>{self.permutation[i]}]' for i in range(len(self.permutation)))
|
|
109
111
|
|
|
110
112
|
def __repr__(self) -> str:
|
cirq/ops/phased_iswap_gate.py
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""ISWAPPowGate conjugated by tensor product Rz(phi) and Rz(-phi)."""
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
from typing import AbstractSet, Any, cast, Dict, Iterator, List, Optional, Sequence, Tuple, Union
|
|
17
19
|
|
|
18
20
|
import numpy as np
|
|
@@ -112,14 +114,14 @@ class PhasedISwapPowGate(eigen_gate.EigenGate):
|
|
|
112
114
|
)
|
|
113
115
|
|
|
114
116
|
def _resolve_parameters_(
|
|
115
|
-
self, resolver:
|
|
116
|
-
) ->
|
|
117
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
118
|
+
) -> PhasedISwapPowGate:
|
|
117
119
|
return self.__class__(
|
|
118
120
|
phase_exponent=protocols.resolve_parameters(self.phase_exponent, resolver, recursive),
|
|
119
121
|
exponent=protocols.resolve_parameters(self.exponent, resolver, recursive),
|
|
120
122
|
)
|
|
121
123
|
|
|
122
|
-
def _with_exponent(self, exponent: value.type_alias.TParamVal) ->
|
|
124
|
+
def _with_exponent(self, exponent: value.type_alias.TParamVal) -> PhasedISwapPowGate:
|
|
123
125
|
return PhasedISwapPowGate(
|
|
124
126
|
phase_exponent=self.phase_exponent, exponent=exponent, global_shift=self.global_shift
|
|
125
127
|
)
|
|
@@ -137,7 +139,7 @@ class PhasedISwapPowGate(eigen_gate.EigenGate):
|
|
|
137
139
|
eigen_components.append((eigenvalue, new_projector))
|
|
138
140
|
return eigen_components
|
|
139
141
|
|
|
140
|
-
def _apply_unitary_(self, args:
|
|
142
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
|
|
141
143
|
if protocols.is_parameterized(self):
|
|
142
144
|
return NotImplemented
|
|
143
145
|
|
|
@@ -156,7 +158,7 @@ class PhasedISwapPowGate(eigen_gate.EigenGate):
|
|
|
156
158
|
)
|
|
157
159
|
return args.available_buffer
|
|
158
160
|
|
|
159
|
-
def _decompose_(self, qubits: Sequence[
|
|
161
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
160
162
|
if len(qubits) != 2:
|
|
161
163
|
raise ValueError(f'Expected two qubits, got {len(qubits)}')
|
|
162
164
|
a, b = qubits
|
|
@@ -189,9 +191,7 @@ class PhasedISwapPowGate(eigen_gate.EigenGate):
|
|
|
189
191
|
}
|
|
190
192
|
)
|
|
191
193
|
|
|
192
|
-
def _circuit_diagram_info_(
|
|
193
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
194
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
194
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
195
195
|
s = f'PhISwap({args.format_real(self._phase_exponent)})'
|
|
196
196
|
return protocols.CircuitDiagramInfo(
|
|
197
197
|
wire_symbols=(s, s), exponent=self._diagram_exponent(args)
|
cirq/ops/phased_x_gate.py
CHANGED
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""An `XPowGate` conjugated by `ZPowGate`s."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import math
|
|
17
20
|
import numbers
|
|
18
21
|
from types import NotImplementedType
|
|
@@ -64,7 +67,7 @@ class PhasedXPowGate(raw_types.Gate):
|
|
|
64
67
|
self._exponent = exponent
|
|
65
68
|
self._global_shift = global_shift
|
|
66
69
|
|
|
67
|
-
def _qasm_(self, args:
|
|
70
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
68
71
|
if cirq.is_parameterized(self):
|
|
69
72
|
return None
|
|
70
73
|
|
|
@@ -92,7 +95,7 @@ class PhasedXPowGate(raw_types.Gate):
|
|
|
92
95
|
qubits[0],
|
|
93
96
|
)
|
|
94
97
|
|
|
95
|
-
def _decompose_(self, qubits: Sequence[
|
|
98
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
|
|
96
99
|
assert len(qubits) == 1
|
|
97
100
|
q = qubits[0]
|
|
98
101
|
z = cirq.Z(q) ** self._phase_exponent
|
|
@@ -113,7 +116,7 @@ class PhasedXPowGate(raw_types.Gate):
|
|
|
113
116
|
def global_shift(self) -> float:
|
|
114
117
|
return self._global_shift
|
|
115
118
|
|
|
116
|
-
def __pow__(self, exponent: Union[float, sympy.Expr]) ->
|
|
119
|
+
def __pow__(self, exponent: Union[float, sympy.Expr]) -> PhasedXPowGate:
|
|
117
120
|
new_exponent = protocols.mul(self._exponent, exponent, NotImplemented)
|
|
118
121
|
if new_exponent is NotImplemented:
|
|
119
122
|
return NotImplemented # pragma: no cover
|
|
@@ -169,9 +172,7 @@ class PhasedXPowGate(raw_types.Gate):
|
|
|
169
172
|
self._phase_exponent
|
|
170
173
|
)
|
|
171
174
|
|
|
172
|
-
def _resolve_parameters_(
|
|
173
|
-
self, resolver: 'cirq.ParamResolver', recursive: bool
|
|
174
|
-
) -> 'PhasedXPowGate':
|
|
175
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> PhasedXPowGate:
|
|
175
176
|
"""See `cirq.SupportsParameterization`."""
|
|
176
177
|
phase_exponent = resolver.value_of(self._phase_exponent, recursive)
|
|
177
178
|
exponent = resolver.value_of(self._exponent, recursive)
|
|
@@ -198,9 +199,7 @@ class PhasedXPowGate(raw_types.Gate):
|
|
|
198
199
|
global_shift=self._global_shift,
|
|
199
200
|
)
|
|
200
201
|
|
|
201
|
-
def _circuit_diagram_info_(
|
|
202
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
203
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
202
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
204
203
|
"""See `cirq.SupportsCircuitDiagramInfo`."""
|
|
205
204
|
|
|
206
205
|
return protocols.CircuitDiagramInfo(
|
cirq/ops/phased_x_z_gate.py
CHANGED
|
@@ -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
|
import numbers
|
|
16
18
|
from typing import AbstractSet, Any, Dict, Iterator, Optional, Sequence, Tuple, TYPE_CHECKING, Union
|
|
17
19
|
|
|
@@ -69,7 +71,7 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
69
71
|
self._axis_phase_exponent = axis_phase_exponent
|
|
70
72
|
|
|
71
73
|
@classmethod
|
|
72
|
-
def from_zyz_angles(cls, z0_rad: float, y_rad: float, z1_rad: float) ->
|
|
74
|
+
def from_zyz_angles(cls, z0_rad: float, y_rad: float, z1_rad: float) -> cirq.PhasedXZGate:
|
|
73
75
|
r"""Create a PhasedXZGate from ZYZ angles.
|
|
74
76
|
|
|
75
77
|
The returned gate is equivalent to $Rz(z0\_rad) Ry(y\_rad) Rz(z1\_rad)$ (in time order).
|
|
@@ -77,14 +79,14 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
77
79
|
return cls.from_zyz_exponents(z0=z0_rad / np.pi, y=y_rad / np.pi, z1=z1_rad / np.pi)
|
|
78
80
|
|
|
79
81
|
@classmethod
|
|
80
|
-
def from_zyz_exponents(cls, z0: float, y: float, z1: float) ->
|
|
82
|
+
def from_zyz_exponents(cls, z0: float, y: float, z1: float) -> cirq.PhasedXZGate:
|
|
81
83
|
"""Create a PhasedXZGate from ZYZ exponents.
|
|
82
84
|
|
|
83
85
|
The returned gate is equivalent to $Z^{z0} Y^y Z^{z1}$ (in time order).
|
|
84
86
|
"""
|
|
85
87
|
return PhasedXZGate(axis_phase_exponent=-z0 + 0.5, x_exponent=y, z_exponent=z0 + z1)
|
|
86
88
|
|
|
87
|
-
def _canonical(self) ->
|
|
89
|
+
def _canonical(self) -> cirq.PhasedXZGate:
|
|
88
90
|
x = self.x_exponent
|
|
89
91
|
z = self.z_exponent
|
|
90
92
|
a = self.axis_phase_exponent
|
|
@@ -146,7 +148,7 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
146
148
|
)
|
|
147
149
|
|
|
148
150
|
@staticmethod
|
|
149
|
-
def from_matrix(mat: np.ndarray) ->
|
|
151
|
+
def from_matrix(mat: np.ndarray) -> cirq.PhasedXZGate:
|
|
150
152
|
pre_phase, rotation, post_phase = linalg.deconstruct_single_qubit_matrix_into_angles(mat)
|
|
151
153
|
pre_phase /= np.pi
|
|
152
154
|
post_phase /= np.pi
|
|
@@ -157,14 +159,14 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
157
159
|
x_exponent=rotation, axis_phase_exponent=-pre_phase, z_exponent=post_phase + pre_phase
|
|
158
160
|
)._canonical()
|
|
159
161
|
|
|
160
|
-
def with_z_exponent(self, z_exponent: Union[float, sympy.Expr]) ->
|
|
162
|
+
def with_z_exponent(self, z_exponent: Union[float, sympy.Expr]) -> cirq.PhasedXZGate:
|
|
161
163
|
return PhasedXZGate(
|
|
162
164
|
axis_phase_exponent=self._axis_phase_exponent,
|
|
163
165
|
x_exponent=self._x_exponent,
|
|
164
166
|
z_exponent=z_exponent,
|
|
165
167
|
)
|
|
166
168
|
|
|
167
|
-
def _qasm_(self, args:
|
|
169
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
168
170
|
from cirq.circuits import qasm_output
|
|
169
171
|
|
|
170
172
|
qasm_gate = qasm_output.QasmUGate(
|
|
@@ -189,13 +191,13 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
189
191
|
z_post = protocols.unitary(ops.Z ** (self._axis_phase_exponent + self._z_exponent))
|
|
190
192
|
return z_post @ x @ z_pre
|
|
191
193
|
|
|
192
|
-
def _decompose_(self, qubits: Sequence[
|
|
194
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
193
195
|
q = qubits[0]
|
|
194
196
|
yield ops.Z(q) ** -self._axis_phase_exponent
|
|
195
197
|
yield ops.X(q) ** self._x_exponent
|
|
196
198
|
yield ops.Z(q) ** (self._axis_phase_exponent + self._z_exponent)
|
|
197
199
|
|
|
198
|
-
def __pow__(self, exponent: float) ->
|
|
200
|
+
def __pow__(self, exponent: float) -> PhasedXZGate:
|
|
199
201
|
if exponent == 1:
|
|
200
202
|
return self
|
|
201
203
|
if exponent == -1:
|
|
@@ -223,8 +225,8 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
223
225
|
)
|
|
224
226
|
|
|
225
227
|
def _resolve_parameters_(
|
|
226
|
-
self, resolver:
|
|
227
|
-
) ->
|
|
228
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
229
|
+
) -> cirq.PhasedXZGate:
|
|
228
230
|
"""See `cirq.SupportsParameterization`."""
|
|
229
231
|
z_exponent = resolver.value_of(self._z_exponent, recursive)
|
|
230
232
|
x_exponent = resolver.value_of(self._x_exponent, recursive)
|
|
@@ -250,7 +252,7 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
250
252
|
z_exponent=z_exponent, x_exponent=x_exponent, axis_phase_exponent=axis_phase_exponent
|
|
251
253
|
)
|
|
252
254
|
|
|
253
|
-
def _phase_by_(self, phase_turns, qubit_index) ->
|
|
255
|
+
def _phase_by_(self, phase_turns, qubit_index) -> cirq.PhasedXZGate:
|
|
254
256
|
"""See `cirq.SupportsPhase`."""
|
|
255
257
|
assert qubit_index == 0
|
|
256
258
|
return PhasedXZGate(
|
|
@@ -259,7 +261,7 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
259
261
|
axis_phase_exponent=self._axis_phase_exponent + phase_turns * 2,
|
|
260
262
|
)
|
|
261
263
|
|
|
262
|
-
def _pauli_expansion_(self) ->
|
|
264
|
+
def _pauli_expansion_(self) -> cirq.LinearDict[str]:
|
|
263
265
|
if protocols.is_parameterized(self):
|
|
264
266
|
return NotImplemented
|
|
265
267
|
x_angle = np.pi * self._x_exponent / 2
|
|
@@ -278,7 +280,7 @@ class PhasedXZGate(raw_types.Gate):
|
|
|
278
280
|
}
|
|
279
281
|
) # yapf: disable
|
|
280
282
|
|
|
281
|
-
def _circuit_diagram_info_(self, args:
|
|
283
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> str:
|
|
282
284
|
"""See `cirq.SupportsCircuitDiagramInfo`."""
|
|
283
285
|
return (
|
|
284
286
|
f'PhXZ('
|
cirq/ops/qid_util.py
CHANGED
|
@@ -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 overload, TYPE_CHECKING, Union
|
|
16
18
|
|
|
17
19
|
if TYPE_CHECKING:
|
|
@@ -19,18 +21,18 @@ if TYPE_CHECKING:
|
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
@overload
|
|
22
|
-
def q(__x: int) ->
|
|
24
|
+
def q(__x: int) -> cirq.LineQubit: ...
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
@overload
|
|
26
|
-
def q(__row: int, __col: int) ->
|
|
28
|
+
def q(__row: int, __col: int) -> cirq.GridQubit: ...
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
@overload
|
|
30
|
-
def q(__name: str) ->
|
|
32
|
+
def q(__name: str) -> cirq.NamedQubit: ...
|
|
31
33
|
|
|
32
34
|
|
|
33
|
-
def q(*args: Union[int, str]) -> Union[
|
|
35
|
+
def q(*args: Union[int, str]) -> Union[cirq.LineQubit, cirq.GridQubit, cirq.NamedQubit]:
|
|
34
36
|
"""Constructs a qubit id of the appropriate type based on args.
|
|
35
37
|
|
|
36
38
|
This is shorthand for constructing qubit ids of common types:
|
cirq/ops/qubit_manager.py
CHANGED
|
@@ -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
|
import abc
|
|
16
18
|
import dataclasses
|
|
17
19
|
from typing import Iterable, List, Tuple, TYPE_CHECKING
|
|
@@ -24,15 +26,15 @@ if TYPE_CHECKING:
|
|
|
24
26
|
|
|
25
27
|
class QubitManager(metaclass=abc.ABCMeta):
|
|
26
28
|
@abc.abstractmethod
|
|
27
|
-
def qalloc(self, n: int, dim: int = 2) -> List[
|
|
29
|
+
def qalloc(self, n: int, dim: int = 2) -> List[cirq.Qid]:
|
|
28
30
|
"""Allocate `n` clean qubits, i.e. qubits guaranteed to be in state |0>."""
|
|
29
31
|
|
|
30
32
|
@abc.abstractmethod
|
|
31
|
-
def qborrow(self, n: int, dim: int = 2) -> List[
|
|
33
|
+
def qborrow(self, n: int, dim: int = 2) -> List[cirq.Qid]:
|
|
32
34
|
"""Allocate `n` dirty qubits, i.e. the returned qubits can be in any state."""
|
|
33
35
|
|
|
34
36
|
@abc.abstractmethod
|
|
35
|
-
def qfree(self, qubits: Iterable[
|
|
37
|
+
def qfree(self, qubits: Iterable[cirq.Qid]) -> None:
|
|
36
38
|
"""Free pre-allocated clean or dirty qubits managed by this qubit manager."""
|
|
37
39
|
|
|
38
40
|
|
|
@@ -49,7 +51,7 @@ class _BaseAncillaQid(raw_types.Qid):
|
|
|
49
51
|
def dimension(self) -> int:
|
|
50
52
|
return self.dim
|
|
51
53
|
|
|
52
|
-
def with_dimension(self, dimension: int) ->
|
|
54
|
+
def with_dimension(self, dimension: int) -> _BaseAncillaQid:
|
|
53
55
|
return dataclasses.replace(self, dim=dimension)
|
|
54
56
|
|
|
55
57
|
def __repr__(self) -> str:
|
|
@@ -82,18 +84,18 @@ class SimpleQubitManager(QubitManager):
|
|
|
82
84
|
self._borrow_id = 0
|
|
83
85
|
self._prefix = prefix
|
|
84
86
|
|
|
85
|
-
def qalloc(self, n: int, dim: int = 2) -> List[
|
|
87
|
+
def qalloc(self, n: int, dim: int = 2) -> List[cirq.Qid]:
|
|
86
88
|
self._clean_id += n
|
|
87
89
|
return [CleanQubit(i, dim, self._prefix) for i in range(self._clean_id - n, self._clean_id)]
|
|
88
90
|
|
|
89
|
-
def qborrow(self, n: int, dim: int = 2) -> List[
|
|
91
|
+
def qborrow(self, n: int, dim: int = 2) -> List[cirq.Qid]:
|
|
90
92
|
self._borrow_id = self._borrow_id + n
|
|
91
93
|
return [
|
|
92
94
|
BorrowableQubit(i, dim, self._prefix)
|
|
93
95
|
for i in range(self._borrow_id - n, self._borrow_id)
|
|
94
96
|
]
|
|
95
97
|
|
|
96
|
-
def qfree(self, qubits: Iterable[
|
|
98
|
+
def qfree(self, qubits: Iterable[cirq.Qid]) -> None:
|
|
97
99
|
for q in qubits:
|
|
98
100
|
good = isinstance(q, CleanQubit) and q.id < self._clean_id
|
|
99
101
|
good |= isinstance(q, BorrowableQubit) and q.id < self._borrow_id
|