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/three_qubit_gates.py
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
"""Common quantum gates that target three qubits."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from typing import (
|
|
18
20
|
AbstractSet,
|
|
19
21
|
Any,
|
|
@@ -144,7 +146,7 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
144
146
|
sweep_abc,
|
|
145
147
|
]
|
|
146
148
|
|
|
147
|
-
def _apply_unitary_(self, args:
|
|
149
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
|
|
148
150
|
if protocols.is_parameterized(self):
|
|
149
151
|
return NotImplemented
|
|
150
152
|
ooo = args.subspace_index(0b111)
|
|
@@ -154,12 +156,10 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
154
156
|
args.target_tensor *= p
|
|
155
157
|
return args.target_tensor
|
|
156
158
|
|
|
157
|
-
def _circuit_diagram_info_(
|
|
158
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
159
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
159
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
160
160
|
return protocols.CircuitDiagramInfo(('@', '@', '@'), exponent=self._diagram_exponent(args))
|
|
161
161
|
|
|
162
|
-
def _qasm_(self, args:
|
|
162
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
163
163
|
if self._exponent != 1:
|
|
164
164
|
return None
|
|
165
165
|
|
|
@@ -206,7 +206,7 @@ class CCZPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
206
206
|
"""
|
|
207
207
|
if num_controls == 0:
|
|
208
208
|
return self
|
|
209
|
-
sub_gate:
|
|
209
|
+
sub_gate: cirq.Gate = self
|
|
210
210
|
if self._global_shift == 0:
|
|
211
211
|
sub_gate = controlled_gate.ControlledGate(
|
|
212
212
|
common_gates.ZPowGate(exponent=self._exponent), num_controls=2
|
|
@@ -253,8 +253,8 @@ class ThreeQubitDiagonalGate(raw_types.Gate):
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
def _resolve_parameters_(
|
|
256
|
-
self, resolver:
|
|
257
|
-
) ->
|
|
256
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
257
|
+
) -> ThreeQubitDiagonalGate:
|
|
258
258
|
return self.__class__(
|
|
259
259
|
[
|
|
260
260
|
protocols.resolve_parameters(angle, resolver, recursive)
|
|
@@ -270,7 +270,7 @@ class ThreeQubitDiagonalGate(raw_types.Gate):
|
|
|
270
270
|
return NotImplemented
|
|
271
271
|
return np.diag([np.exp(1j * angle) for angle in self._diag_angles_radians])
|
|
272
272
|
|
|
273
|
-
def _apply_unitary_(self, args:
|
|
273
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
|
|
274
274
|
if self._is_parameterized_():
|
|
275
275
|
return NotImplemented
|
|
276
276
|
for index, angle in enumerate(self._diag_angles_radians):
|
|
@@ -279,16 +279,14 @@ class ThreeQubitDiagonalGate(raw_types.Gate):
|
|
|
279
279
|
args.target_tensor[subspace_index] *= np.exp(1j * angle)
|
|
280
280
|
return args.target_tensor
|
|
281
281
|
|
|
282
|
-
def _circuit_diagram_info_(
|
|
283
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
284
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
282
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
285
283
|
rounded_angles = np.array(self._diag_angles_radians)
|
|
286
284
|
if args.precision is not None:
|
|
287
285
|
rounded_angles = rounded_angles.round(args.precision)
|
|
288
286
|
diag_str = f"diag({', '.join(proper_repr(angle) for angle in rounded_angles)})"
|
|
289
287
|
return protocols.CircuitDiagramInfo((diag_str, '#2', '#3'))
|
|
290
288
|
|
|
291
|
-
def __pow__(self, exponent: Any) ->
|
|
289
|
+
def __pow__(self, exponent: Any) -> ThreeQubitDiagonalGate:
|
|
292
290
|
if not isinstance(exponent, (int, float, sympy.Basic)):
|
|
293
291
|
return NotImplemented
|
|
294
292
|
return ThreeQubitDiagonalGate(
|
|
@@ -451,7 +449,7 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
451
449
|
def qubit_index_to_equivalence_group_key(self, index):
|
|
452
450
|
return index < 2
|
|
453
451
|
|
|
454
|
-
def _apply_unitary_(self, args:
|
|
452
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
|
|
455
453
|
if protocols.is_parameterized(self):
|
|
456
454
|
return NotImplemented
|
|
457
455
|
p = 1j ** (2 * self._exponent * self._global_shift)
|
|
@@ -471,14 +469,12 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
471
469
|
yield CCZPowGate(exponent=self._exponent, global_shift=self.global_shift).on(c1, c2, t)
|
|
472
470
|
yield common_gates.H(t)
|
|
473
471
|
|
|
474
|
-
def _circuit_diagram_info_(
|
|
475
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
476
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
472
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
477
473
|
return protocols.CircuitDiagramInfo(
|
|
478
474
|
('@', '@', 'X'), exponent=self._diagram_exponent(args), exponent_qubit_index=2
|
|
479
475
|
)
|
|
480
476
|
|
|
481
|
-
def _qasm_(self, args:
|
|
477
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
482
478
|
if self._exponent != 1:
|
|
483
479
|
return None
|
|
484
480
|
|
|
@@ -520,7 +516,7 @@ class CCXPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate):
|
|
|
520
516
|
"""
|
|
521
517
|
if num_controls == 0:
|
|
522
518
|
return self
|
|
523
|
-
sub_gate:
|
|
519
|
+
sub_gate: cirq.Gate = self
|
|
524
520
|
if self._global_shift == 0:
|
|
525
521
|
sub_gate = controlled_gate.ControlledGate(
|
|
526
522
|
common_gates.XPowGate(exponent=self._exponent), num_controls=2
|
|
@@ -572,8 +568,8 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
572
568
|
return self._decompose_outside_control(c, t1, t2)
|
|
573
569
|
|
|
574
570
|
def _decompose_inside_control(
|
|
575
|
-
self, target1:
|
|
576
|
-
) -> Iterator[
|
|
571
|
+
self, target1: cirq.Qid, control: cirq.Qid, target2: cirq.Qid
|
|
572
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
577
573
|
"""A decomposition assuming the control separates the targets.
|
|
578
574
|
|
|
579
575
|
target1: ─@─X───────T──────@────────@─────────X───@─────X^-0.5─
|
|
@@ -608,7 +604,7 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
608
604
|
yield common_gates.S(c) ** -1
|
|
609
605
|
yield pauli_gates.X(a) ** -0.5
|
|
610
606
|
|
|
611
|
-
def _apply_unitary_(self, args:
|
|
607
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
|
|
612
608
|
return protocols.apply_unitary(
|
|
613
609
|
controlled_gate.ControlledGate(swap_gates.SWAP),
|
|
614
610
|
protocols.ApplyUnitaryArgs(args.target_tensor, args.available_buffer, args.axes),
|
|
@@ -616,8 +612,8 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
616
612
|
)
|
|
617
613
|
|
|
618
614
|
def _decompose_outside_control(
|
|
619
|
-
self, control:
|
|
620
|
-
) -> Iterator[
|
|
615
|
+
self, control: cirq.Qid, near_target: cirq.Qid, far_target: cirq.Qid
|
|
616
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
621
617
|
"""A decomposition assuming one of the targets is in the middle.
|
|
622
618
|
|
|
623
619
|
control: ───T──────@────────@───@────────────@────────────────
|
|
@@ -652,14 +648,12 @@ class CSwapGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
652
648
|
def _unitary_(self) -> np.ndarray:
|
|
653
649
|
return linalg.block_diag(np.diag([1, 1, 1, 1, 1]), np.array([[0, 1], [1, 0]]), np.diag([1]))
|
|
654
650
|
|
|
655
|
-
def _circuit_diagram_info_(
|
|
656
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
657
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
651
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
658
652
|
if not args.use_unicode_characters:
|
|
659
653
|
return protocols.CircuitDiagramInfo(('@', 'swap', 'swap'))
|
|
660
654
|
return protocols.CircuitDiagramInfo(('@', '×', '×'))
|
|
661
655
|
|
|
662
|
-
def _qasm_(self, args:
|
|
656
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
663
657
|
args.validate_version('2.0', '3.0')
|
|
664
658
|
return args.format('cswap {0},{1},{2};\n', qubits[0], qubits[1], qubits[2])
|
|
665
659
|
|
|
@@ -18,6 +18,8 @@ The gate is used to create a 4x4 matrix with the diagonal elements
|
|
|
18
18
|
passed as a list.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
21
23
|
from typing import AbstractSet, Any, Dict, Iterator, Optional, Sequence, Tuple, TYPE_CHECKING
|
|
22
24
|
|
|
23
25
|
import numpy as np
|
|
@@ -80,8 +82,8 @@ class TwoQubitDiagonalGate(raw_types.Gate):
|
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
def _resolve_parameters_(
|
|
83
|
-
self, resolver:
|
|
84
|
-
) ->
|
|
85
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
86
|
+
) -> TwoQubitDiagonalGate:
|
|
85
87
|
return TwoQubitDiagonalGate(
|
|
86
88
|
protocols.resolve_parameters(self._diag_angles_radians, resolver, recursive)
|
|
87
89
|
)
|
|
@@ -94,7 +96,7 @@ class TwoQubitDiagonalGate(raw_types.Gate):
|
|
|
94
96
|
return None
|
|
95
97
|
return np.diag([np.exp(1j * angle) for angle in self._diag_angles_radians])
|
|
96
98
|
|
|
97
|
-
def _decompose_(self, qubits: Sequence[
|
|
99
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
98
100
|
x0, x1, x2, x3 = self._diag_angles_radians
|
|
99
101
|
q0, q1 = qubits
|
|
100
102
|
yield common_gates.ZPowGate(exponent=x2 / np.pi).on(q0)
|
|
@@ -104,7 +106,7 @@ class TwoQubitDiagonalGate(raw_types.Gate):
|
|
|
104
106
|
yield common_gates.CZPowGate(exponent=x0 / np.pi).on(q0, q1)
|
|
105
107
|
yield common_gates.XPowGate().on_each(q0, q1)
|
|
106
108
|
|
|
107
|
-
def _apply_unitary_(self, args:
|
|
109
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray:
|
|
108
110
|
if self._is_parameterized_():
|
|
109
111
|
return NotImplemented
|
|
110
112
|
for index, angle in enumerate(self._diag_angles_radians):
|
|
@@ -112,16 +114,14 @@ class TwoQubitDiagonalGate(raw_types.Gate):
|
|
|
112
114
|
args.target_tensor[subspace_index] *= np.exp(1j * angle)
|
|
113
115
|
return args.target_tensor
|
|
114
116
|
|
|
115
|
-
def _circuit_diagram_info_(
|
|
116
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
117
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
117
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
118
118
|
rounded_angles = np.array(self._diag_angles_radians)
|
|
119
119
|
if args.precision is not None:
|
|
120
120
|
rounded_angles = rounded_angles.round(args.precision)
|
|
121
121
|
diag_str = f"diag({', '.join(proper_repr(angle) for angle in rounded_angles)})"
|
|
122
122
|
return protocols.CircuitDiagramInfo((diag_str, '#2'))
|
|
123
123
|
|
|
124
|
-
def __pow__(self, exponent: Any) ->
|
|
124
|
+
def __pow__(self, exponent: Any) -> TwoQubitDiagonalGate:
|
|
125
125
|
if not isinstance(exponent, (int, float, sympy.Basic)):
|
|
126
126
|
return NotImplemented
|
|
127
127
|
angles = []
|
|
@@ -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, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
import numpy as np
|
|
@@ -58,7 +60,7 @@ class UniformSuperpositionGate(raw_types.Gate):
|
|
|
58
60
|
self._m_value = m_value
|
|
59
61
|
self._num_qubits = num_qubits
|
|
60
62
|
|
|
61
|
-
def _decompose_(self, qubits: Sequence[
|
|
63
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
62
64
|
"""Decomposes the gate into a sequence of standard gates.
|
|
63
65
|
Implements the construction from https://arxiv.org/pdf/2306.11747.
|
|
64
66
|
"""
|
cirq/ops/wait_gate.py
CHANGED
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
from typing import AbstractSet, Any, Dict, Optional, Tuple, TYPE_CHECKING
|
|
15
18
|
|
|
16
19
|
from cirq import protocols, value
|
|
@@ -30,7 +33,7 @@ class WaitGate(raw_types.Gate):
|
|
|
30
33
|
|
|
31
34
|
def __init__(
|
|
32
35
|
self,
|
|
33
|
-
duration:
|
|
36
|
+
duration: cirq.DURATION_LIKE,
|
|
34
37
|
num_qubits: Optional[int] = None,
|
|
35
38
|
qid_shape: Optional[Tuple[int, ...]] = None,
|
|
36
39
|
) -> None:
|
|
@@ -66,7 +69,7 @@ class WaitGate(raw_types.Gate):
|
|
|
66
69
|
self._qid_shape = qid_shape
|
|
67
70
|
|
|
68
71
|
@property
|
|
69
|
-
def duration(self) ->
|
|
72
|
+
def duration(self) -> cirq.Duration:
|
|
70
73
|
return self._duration
|
|
71
74
|
|
|
72
75
|
def _is_parameterized_(self) -> bool:
|
|
@@ -75,7 +78,7 @@ class WaitGate(raw_types.Gate):
|
|
|
75
78
|
def _parameter_names_(self) -> AbstractSet[str]:
|
|
76
79
|
return protocols.parameter_names(self.duration)
|
|
77
80
|
|
|
78
|
-
def _resolve_parameters_(self, resolver:
|
|
81
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> WaitGate:
|
|
79
82
|
return WaitGate(
|
|
80
83
|
protocols.resolve_parameters(self.duration, resolver, recursive),
|
|
81
84
|
qid_shape=self._qid_shape,
|
|
@@ -132,12 +135,12 @@ class WaitGate(raw_types.Gate):
|
|
|
132
135
|
|
|
133
136
|
|
|
134
137
|
def wait(
|
|
135
|
-
*target:
|
|
136
|
-
duration:
|
|
137
|
-
picos:
|
|
138
|
-
nanos:
|
|
139
|
-
micros:
|
|
140
|
-
millis:
|
|
138
|
+
*target: cirq.Qid,
|
|
139
|
+
duration: cirq.DURATION_LIKE = None,
|
|
140
|
+
picos: cirq.TParamVal = 0,
|
|
141
|
+
nanos: cirq.TParamVal = 0,
|
|
142
|
+
micros: cirq.TParamVal = 0,
|
|
143
|
+
millis: cirq.TParamVal = 0,
|
|
141
144
|
) -> raw_types.Operation:
|
|
142
145
|
"""Creates a WaitGate applied to all the given qubits.
|
|
143
146
|
|
|
@@ -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 types import NotImplementedType
|
|
16
18
|
from typing import Any, Optional, Sequence, TYPE_CHECKING, Union
|
|
17
19
|
|
|
@@ -28,7 +30,7 @@ class SupportsActOn(Protocol):
|
|
|
28
30
|
"""An object that explicitly specifies how to act on simulator states."""
|
|
29
31
|
|
|
30
32
|
@doc_private
|
|
31
|
-
def _act_on_(self, sim_state:
|
|
33
|
+
def _act_on_(self, sim_state: cirq.SimulationStateBase) -> Union[NotImplementedType, bool]:
|
|
32
34
|
"""Applies an action to the given argument, if it is a supported type.
|
|
33
35
|
|
|
34
36
|
For example, unitary operations can implement an `_act_on_` method that
|
|
@@ -59,7 +61,7 @@ class SupportsActOnQubits(Protocol):
|
|
|
59
61
|
|
|
60
62
|
@doc_private
|
|
61
63
|
def _act_on_(
|
|
62
|
-
self, sim_state:
|
|
64
|
+
self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]
|
|
63
65
|
) -> Union[NotImplementedType, bool]:
|
|
64
66
|
"""Applies an action to the given argument, if it is a supported type.
|
|
65
67
|
|
|
@@ -88,8 +90,8 @@ class SupportsActOnQubits(Protocol):
|
|
|
88
90
|
|
|
89
91
|
def act_on(
|
|
90
92
|
action: Any,
|
|
91
|
-
sim_state:
|
|
92
|
-
qubits: Optional[Sequence[
|
|
93
|
+
sim_state: cirq.SimulationStateBase,
|
|
94
|
+
qubits: Optional[Sequence[cirq.Qid]] = None,
|
|
93
95
|
*,
|
|
94
96
|
allow_decompose: bool = True,
|
|
95
97
|
):
|
|
@@ -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, Sequence, Tuple
|
|
15
18
|
|
|
16
19
|
import numpy as np
|
|
@@ -34,7 +37,7 @@ class ExampleSimulationState(cirq.SimulationState):
|
|
|
34
37
|
self.fallback_result = fallback_result
|
|
35
38
|
|
|
36
39
|
def _act_on_fallback_(
|
|
37
|
-
self, action: Any, qubits: Sequence[
|
|
40
|
+
self, action: Any, qubits: Sequence[cirq.Qid], allow_decompose: bool = True
|
|
38
41
|
):
|
|
39
42
|
return self.fallback_result
|
|
40
43
|
|
|
@@ -62,10 +65,10 @@ def test_act_on_fallback_errors():
|
|
|
62
65
|
def test_act_on_errors():
|
|
63
66
|
class Op(cirq.Operation):
|
|
64
67
|
@property
|
|
65
|
-
def qubits(self) -> Tuple[
|
|
68
|
+
def qubits(self) -> Tuple[cirq.Qid, ...]: # type: ignore[empty-body]
|
|
66
69
|
pass
|
|
67
70
|
|
|
68
|
-
def with_qubits(self, *new_qubits:
|
|
71
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> Self: # type: ignore[empty-body]
|
|
69
72
|
pass
|
|
70
73
|
|
|
71
74
|
def _act_on_(self, sim_state):
|
|
@@ -79,10 +82,10 @@ def test_act_on_errors():
|
|
|
79
82
|
def test_qubits_not_allowed_for_operations():
|
|
80
83
|
class Op(cirq.Operation):
|
|
81
84
|
@property
|
|
82
|
-
def qubits(self) -> Tuple[
|
|
85
|
+
def qubits(self) -> Tuple[cirq.Qid, ...]: # type: ignore[empty-body]
|
|
83
86
|
pass
|
|
84
87
|
|
|
85
|
-
def with_qubits(self, *new_qubits:
|
|
88
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> Self: # type: ignore[empty-body]
|
|
86
89
|
pass
|
|
87
90
|
|
|
88
91
|
state = ExampleSimulationState()
|
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
"""A protocol for implementing high performance unitary left-multiplies."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
import warnings
|
|
18
|
-
from types import NotImplementedType
|
|
20
|
+
from types import EllipsisType, NotImplementedType
|
|
19
21
|
from typing import Any, cast, Iterable, Optional, Sequence, Tuple, TYPE_CHECKING, TypeVar, Union
|
|
20
22
|
|
|
21
23
|
import numpy as np
|
|
@@ -112,7 +114,7 @@ class ApplyUnitaryArgs:
|
|
|
112
114
|
@staticmethod
|
|
113
115
|
def default(
|
|
114
116
|
num_qubits: Optional[int] = None, *, qid_shape: Optional[Tuple[int, ...]] = None
|
|
115
|
-
) ->
|
|
117
|
+
) -> ApplyUnitaryArgs:
|
|
116
118
|
"""A default instance starting in state |0⟩.
|
|
117
119
|
|
|
118
120
|
Specify exactly one argument.
|
|
@@ -138,7 +140,7 @@ class ApplyUnitaryArgs:
|
|
|
138
140
|
@classmethod
|
|
139
141
|
def for_unitary(
|
|
140
142
|
cls, num_qubits: Optional[int] = None, *, qid_shape: Optional[Tuple[int, ...]] = None
|
|
141
|
-
) ->
|
|
143
|
+
) -> ApplyUnitaryArgs:
|
|
142
144
|
"""A default instance corresponding to an identity matrix.
|
|
143
145
|
|
|
144
146
|
Specify exactly one argument.
|
|
@@ -162,7 +164,7 @@ class ApplyUnitaryArgs:
|
|
|
162
164
|
state = qis.eye_tensor(qid_shape, dtype=np.complex128)
|
|
163
165
|
return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
|
|
164
166
|
|
|
165
|
-
def with_axes_transposed_to_start(self) ->
|
|
167
|
+
def with_axes_transposed_to_start(self) -> ApplyUnitaryArgs:
|
|
166
168
|
"""Returns a transposed view of the same arguments.
|
|
167
169
|
|
|
168
170
|
Returns:
|
|
@@ -181,7 +183,7 @@ class ApplyUnitaryArgs:
|
|
|
181
183
|
|
|
182
184
|
def _for_operation_with_qid_shape(
|
|
183
185
|
self, indices: Iterable[int], slices: Tuple[Union[int, slice], ...]
|
|
184
|
-
) ->
|
|
186
|
+
) -> ApplyUnitaryArgs:
|
|
185
187
|
"""Creates a sliced and transposed view of `self` appropriate for an
|
|
186
188
|
operation with shape `qid_shape` on qubits with the given indices.
|
|
187
189
|
|
|
@@ -213,7 +215,7 @@ class ApplyUnitaryArgs:
|
|
|
213
215
|
|
|
214
216
|
def subspace_index(
|
|
215
217
|
self, little_endian_bits_int: int = 0, *, big_endian_bits_int: int = 0
|
|
216
|
-
) -> Tuple[Union[slice, int,
|
|
218
|
+
) -> Tuple[Union[slice, int, EllipsisType], ...]:
|
|
217
219
|
"""An index for the subspace where the target axes equal a value.
|
|
218
220
|
|
|
219
221
|
Args:
|
|
@@ -506,7 +508,7 @@ def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> Opt
|
|
|
506
508
|
|
|
507
509
|
def apply_unitaries(
|
|
508
510
|
unitary_values: Iterable[Any],
|
|
509
|
-
qubits: Sequence[
|
|
511
|
+
qubits: Sequence[cirq.Qid],
|
|
510
512
|
args: Optional[ApplyUnitaryArgs] = None,
|
|
511
513
|
default: Any = RaiseTypeErrorIfNotProvided,
|
|
512
514
|
) -> Optional[np.ndarray]:
|
|
@@ -589,7 +591,7 @@ def apply_unitaries(
|
|
|
589
591
|
|
|
590
592
|
|
|
591
593
|
def _incorporate_result_into_target(
|
|
592
|
-
args:
|
|
594
|
+
args: ApplyUnitaryArgs, sub_args: ApplyUnitaryArgs, sub_result: np.ndarray
|
|
593
595
|
):
|
|
594
596
|
"""Takes the result of calling `_apply_unitary_` on `sub_args` and
|
|
595
597
|
copies it back into `args.target_tensor` or `args.available_buffer` as
|
|
@@ -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 re
|
|
16
18
|
from fractions import Fraction
|
|
17
19
|
from typing import (
|
|
@@ -104,7 +106,7 @@ class CircuitDiagramInfo:
|
|
|
104
106
|
)
|
|
105
107
|
|
|
106
108
|
def _wire_symbols_including_formatted_exponent(
|
|
107
|
-
self, args:
|
|
109
|
+
self, args: cirq.CircuitDiagramInfoArgs, *, preferred_exponent_index: Optional[int] = None
|
|
108
110
|
) -> List[str]:
|
|
109
111
|
result = list(self.wire_symbols)
|
|
110
112
|
exponent = self._formatted_exponent(args)
|
|
@@ -122,7 +124,7 @@ class CircuitDiagramInfo:
|
|
|
122
124
|
result[k] += f"^{exponent}"
|
|
123
125
|
return result
|
|
124
126
|
|
|
125
|
-
def _formatted_exponent(self, args:
|
|
127
|
+
def _formatted_exponent(self, args: cirq.CircuitDiagramInfoArgs) -> Optional[str]:
|
|
126
128
|
if protocols.is_parameterized(self.exponent):
|
|
127
129
|
name = str(self.exponent)
|
|
128
130
|
return f'({name})' if _is_exposed_formula(name) else name
|
|
@@ -195,15 +197,15 @@ class CircuitDiagramInfoArgs:
|
|
|
195
197
|
right (transpose is False), or from top to bottom.
|
|
196
198
|
"""
|
|
197
199
|
|
|
198
|
-
UNINFORMED_DEFAULT:
|
|
200
|
+
UNINFORMED_DEFAULT: CircuitDiagramInfoArgs
|
|
199
201
|
|
|
200
202
|
def __init__(
|
|
201
203
|
self,
|
|
202
|
-
known_qubits: Optional[Iterable[
|
|
204
|
+
known_qubits: Optional[Iterable[cirq.Qid]],
|
|
203
205
|
known_qubit_count: Optional[int],
|
|
204
206
|
use_unicode_characters: bool,
|
|
205
207
|
precision: Optional[int],
|
|
206
|
-
label_map: Optional[Dict[
|
|
208
|
+
label_map: Optional[Dict[cirq.LabelEntity, int]],
|
|
207
209
|
include_tags: bool = True,
|
|
208
210
|
transpose: bool = False,
|
|
209
211
|
) -> None:
|
|
@@ -251,7 +253,7 @@ class CircuitDiagramInfoArgs:
|
|
|
251
253
|
return str(val)
|
|
252
254
|
return f'{float(val):.{self.precision}}'
|
|
253
255
|
|
|
254
|
-
def format_complex(self, val: Union[sympy.Basic, int, float,
|
|
256
|
+
def format_complex(self, val: Union[sympy.Basic, int, float, cirq.TParamValComplex]) -> str:
|
|
255
257
|
if isinstance(val, sympy.Basic):
|
|
256
258
|
return str(val)
|
|
257
259
|
c = complex(val)
|
|
@@ -336,8 +338,8 @@ RaiseTypeErrorIfNotProvided = CircuitDiagramInfo(())
|
|
|
336
338
|
|
|
337
339
|
|
|
338
340
|
def _op_info_with_fallback(
|
|
339
|
-
op:
|
|
340
|
-
) ->
|
|
341
|
+
op: cirq.Operation, args: cirq.CircuitDiagramInfoArgs
|
|
342
|
+
) -> cirq.CircuitDiagramInfo:
|
|
341
343
|
info = protocols.circuit_diagram_info(op, args, None)
|
|
342
344
|
rows: List[LabelEntity] = list(op.qubits)
|
|
343
345
|
if args.label_map is not None:
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""Protocol for object that have control keys."""
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
from types import NotImplementedType
|
|
17
19
|
from typing import Any, FrozenSet, TYPE_CHECKING, Union
|
|
18
20
|
|
|
@@ -35,7 +37,7 @@ class SupportsControlKey(Protocol):
|
|
|
35
37
|
"""
|
|
36
38
|
|
|
37
39
|
@doc_private
|
|
38
|
-
def _control_keys_(self) -> Union[FrozenSet[
|
|
40
|
+
def _control_keys_(self) -> Union[FrozenSet[cirq.MeasurementKey], NotImplementedType, None]:
|
|
39
41
|
"""Return the keys for controls referenced by the receiving object.
|
|
40
42
|
|
|
41
43
|
Returns:
|
|
@@ -44,7 +46,7 @@ class SupportsControlKey(Protocol):
|
|
|
44
46
|
"""
|
|
45
47
|
|
|
46
48
|
|
|
47
|
-
def control_keys(val: Any) -> FrozenSet[
|
|
49
|
+
def control_keys(val: Any) -> FrozenSet[cirq.MeasurementKey]:
|
|
48
50
|
"""Gets the keys that the value is classically controlled by.
|
|
49
51
|
|
|
50
52
|
Args:
|
|
@@ -62,7 +64,7 @@ def control_keys(val: Any) -> FrozenSet['cirq.MeasurementKey']:
|
|
|
62
64
|
return frozenset()
|
|
63
65
|
|
|
64
66
|
|
|
65
|
-
def measurement_keys_touched(val: Any) -> FrozenSet[
|
|
67
|
+
def measurement_keys_touched(val: Any) -> FrozenSet[cirq.MeasurementKey]:
|
|
66
68
|
"""Returns all the measurement keys used by the value.
|
|
67
69
|
|
|
68
70
|
This would be the case if the value is or contains a measurement gate, or
|