cirq-core 1.6.0.dev20250423233500__py3-none-any.whl → 1.6.0.dev20250425004112__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 +25 -22
- cirq/protocols/decompose_protocol_test.py +5 -2
- cirq/protocols/inverse_protocol.py +10 -8
- {cirq_core-1.6.0.dev20250423233500.dist-info → cirq_core-1.6.0.dev20250425004112.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250423233500.dist-info → cirq_core-1.6.0.dev20250425004112.dist-info}/RECORD +57 -57
- {cirq_core-1.6.0.dev20250423233500.dist-info → cirq_core-1.6.0.dev20250425004112.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250423233500.dist-info → cirq_core-1.6.0.dev20250425004112.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250423233500.dist-info → cirq_core-1.6.0.dev20250425004112.dist-info}/top_level.txt +0 -0
cirq/ops/gate_operation.py
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
"""Basic types defining qubits, gates, and operations."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
import re
|
|
18
20
|
import warnings
|
|
19
21
|
from types import NotImplementedType
|
|
@@ -51,7 +53,7 @@ class GateOperation(raw_types.Operation):
|
|
|
51
53
|
Objects of this type are immutable.
|
|
52
54
|
"""
|
|
53
55
|
|
|
54
|
-
def __init__(self, gate:
|
|
56
|
+
def __init__(self, gate: cirq.Gate, qubits: Sequence[cirq.Qid]) -> None:
|
|
55
57
|
"""Inits GateOperation.
|
|
56
58
|
|
|
57
59
|
Args:
|
|
@@ -63,19 +65,19 @@ class GateOperation(raw_types.Operation):
|
|
|
63
65
|
self._qubits = tuple(qubits)
|
|
64
66
|
|
|
65
67
|
@property
|
|
66
|
-
def gate(self) ->
|
|
68
|
+
def gate(self) -> cirq.Gate:
|
|
67
69
|
"""The gate applied by the operation."""
|
|
68
70
|
return self._gate
|
|
69
71
|
|
|
70
72
|
@property
|
|
71
|
-
def qubits(self) -> Tuple[
|
|
73
|
+
def qubits(self) -> Tuple[cirq.Qid, ...]:
|
|
72
74
|
"""The qubits targeted by the operation."""
|
|
73
75
|
return self._qubits
|
|
74
76
|
|
|
75
|
-
def with_qubits(self, *new_qubits:
|
|
77
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> Self:
|
|
76
78
|
return cast(Self, self.gate.on(*new_qubits))
|
|
77
79
|
|
|
78
|
-
def with_gate(self, new_gate:
|
|
80
|
+
def with_gate(self, new_gate: cirq.Gate) -> cirq.Operation:
|
|
79
81
|
if self.gate is new_gate:
|
|
80
82
|
# As GateOperation is immutable, this can return the original.
|
|
81
83
|
return self
|
|
@@ -109,7 +111,7 @@ class GateOperation(raw_types.Operation):
|
|
|
109
111
|
return new_gate.on(*self.qubits)
|
|
110
112
|
|
|
111
113
|
def _with_rescoped_keys_(
|
|
112
|
-
self, path: Tuple[str, ...], bindable_keys: FrozenSet[
|
|
114
|
+
self, path: Tuple[str, ...], bindable_keys: FrozenSet[cirq.MeasurementKey]
|
|
113
115
|
):
|
|
114
116
|
new_gate = protocols.with_rescoped_keys(self.gate, path, bindable_keys)
|
|
115
117
|
if new_gate is self.gate:
|
|
@@ -142,10 +144,10 @@ class GateOperation(raw_types.Operation):
|
|
|
142
144
|
|
|
143
145
|
def _group_interchangeable_qubits(
|
|
144
146
|
self,
|
|
145
|
-
) -> Tuple[Union[
|
|
147
|
+
) -> Tuple[Union[cirq.Qid, Tuple[int, FrozenSet[cirq.Qid]]], ...]:
|
|
146
148
|
if not isinstance(self.gate, gate_features.InterchangeableQubitsGate):
|
|
147
149
|
return self.qubits
|
|
148
|
-
groups: Dict[int, List[
|
|
150
|
+
groups: Dict[int, List[cirq.Qid]] = {}
|
|
149
151
|
for i, q in enumerate(self.qubits):
|
|
150
152
|
k = self.gate.qubit_index_to_equivalence_group_key(i)
|
|
151
153
|
groups.setdefault(k, []).append(q)
|
|
@@ -160,12 +162,12 @@ class GateOperation(raw_types.Operation):
|
|
|
160
162
|
def _num_qubits_(self):
|
|
161
163
|
return len(self._qubits)
|
|
162
164
|
|
|
163
|
-
def _decompose_(self) ->
|
|
165
|
+
def _decompose_(self) -> cirq.OP_TREE:
|
|
164
166
|
return self._decompose_with_context_()
|
|
165
167
|
|
|
166
168
|
def _decompose_with_context_(
|
|
167
|
-
self, context: Optional[
|
|
168
|
-
) ->
|
|
169
|
+
self, context: Optional[cirq.DecompositionContext] = None
|
|
170
|
+
) -> cirq.OP_TREE:
|
|
169
171
|
return protocols.decompose_once_with_qubits(
|
|
170
172
|
self.gate, self.qubits, NotImplemented, flatten=False, context=context
|
|
171
173
|
)
|
|
@@ -177,7 +179,7 @@ class GateOperation(raw_types.Operation):
|
|
|
177
179
|
return NotImplemented
|
|
178
180
|
|
|
179
181
|
def _apply_unitary_(
|
|
180
|
-
self, args:
|
|
182
|
+
self, args: protocols.ApplyUnitaryArgs
|
|
181
183
|
) -> Union[np.ndarray, None, NotImplementedType]:
|
|
182
184
|
getter = getattr(self.gate, '_apply_unitary_', None)
|
|
183
185
|
if getter is not None:
|
|
@@ -218,7 +220,7 @@ class GateOperation(raw_types.Operation):
|
|
|
218
220
|
return NotImplemented
|
|
219
221
|
|
|
220
222
|
def _apply_channel_(
|
|
221
|
-
self, args:
|
|
223
|
+
self, args: protocols.ApplyChannelArgs
|
|
222
224
|
) -> Union[np.ndarray, None, NotImplementedType]:
|
|
223
225
|
getter = getattr(self.gate, '_apply_channel_', None)
|
|
224
226
|
if getter is not None:
|
|
@@ -256,7 +258,7 @@ class GateOperation(raw_types.Operation):
|
|
|
256
258
|
return getter()
|
|
257
259
|
return NotImplemented
|
|
258
260
|
|
|
259
|
-
def _measurement_key_obj_(self) -> Optional[
|
|
261
|
+
def _measurement_key_obj_(self) -> Optional[cirq.MeasurementKey]:
|
|
260
262
|
getter = getattr(self.gate, '_measurement_key_obj_', None)
|
|
261
263
|
if getter is not None:
|
|
262
264
|
return getter()
|
|
@@ -264,13 +266,13 @@ class GateOperation(raw_types.Operation):
|
|
|
264
266
|
|
|
265
267
|
def _measurement_key_objs_(
|
|
266
268
|
self,
|
|
267
|
-
) -> Union[FrozenSet[
|
|
269
|
+
) -> Union[FrozenSet[cirq.MeasurementKey], NotImplementedType, None]:
|
|
268
270
|
getter = getattr(self.gate, '_measurement_key_objs_', None)
|
|
269
271
|
if getter is not None:
|
|
270
272
|
return getter()
|
|
271
273
|
return NotImplemented
|
|
272
274
|
|
|
273
|
-
def _act_on_(self, sim_state:
|
|
275
|
+
def _act_on_(self, sim_state: cirq.SimulationStateBase):
|
|
274
276
|
getter = getattr(self.gate, '_act_on_', None)
|
|
275
277
|
if getter is not None:
|
|
276
278
|
return getter(sim_state, self.qubits)
|
|
@@ -288,15 +290,11 @@ class GateOperation(raw_types.Operation):
|
|
|
288
290
|
return getter()
|
|
289
291
|
return NotImplemented
|
|
290
292
|
|
|
291
|
-
def _resolve_parameters_(
|
|
292
|
-
self, resolver: 'cirq.ParamResolver', recursive: bool
|
|
293
|
-
) -> 'cirq.Operation':
|
|
293
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> cirq.Operation:
|
|
294
294
|
resolved_gate = protocols.resolve_parameters(self.gate, resolver, recursive)
|
|
295
295
|
return self.with_gate(resolved_gate)
|
|
296
296
|
|
|
297
|
-
def _circuit_diagram_info_(
|
|
298
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
299
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
297
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
300
298
|
return protocols.circuit_diagram_info(self.gate, args, NotImplemented)
|
|
301
299
|
|
|
302
300
|
def _decompose_into_clifford_(self):
|
|
@@ -311,13 +309,13 @@ class GateOperation(raw_types.Operation):
|
|
|
311
309
|
return getter()
|
|
312
310
|
return NotImplemented
|
|
313
311
|
|
|
314
|
-
def _phase_by_(self, phase_turns: float, qubit_index: int) ->
|
|
312
|
+
def _phase_by_(self, phase_turns: float, qubit_index: int) -> GateOperation:
|
|
315
313
|
phased_gate = protocols.phase_by(self.gate, phase_turns, qubit_index, default=None)
|
|
316
314
|
if phased_gate is None:
|
|
317
315
|
return NotImplemented
|
|
318
316
|
return GateOperation(phased_gate, self._qubits)
|
|
319
317
|
|
|
320
|
-
def __pow__(self, exponent: Any) ->
|
|
318
|
+
def __pow__(self, exponent: Any) -> cirq.Operation:
|
|
321
319
|
"""Raise gate to a power, then reapply to the same qubits.
|
|
322
320
|
|
|
323
321
|
Only works if the gate implements cirq.ExtrapolatableEffect.
|
|
@@ -348,7 +346,7 @@ class GateOperation(raw_types.Operation):
|
|
|
348
346
|
def __rmul__(self, other: Any) -> Any:
|
|
349
347
|
return self.gate._rmul_with_qubits(self._qubits, other)
|
|
350
348
|
|
|
351
|
-
def _qasm_(self, args:
|
|
349
|
+
def _qasm_(self, args: protocols.QasmArgs) -> Optional[str]:
|
|
352
350
|
if isinstance(self.gate, ops.GlobalPhaseGate):
|
|
353
351
|
warnings.warn(
|
|
354
352
|
"OpenQASM 2.0 does not support global phase."
|
|
@@ -370,11 +368,11 @@ class GateOperation(raw_types.Operation):
|
|
|
370
368
|
|
|
371
369
|
def controlled_by(
|
|
372
370
|
self,
|
|
373
|
-
*control_qubits:
|
|
371
|
+
*control_qubits: cirq.Qid,
|
|
374
372
|
control_values: Optional[
|
|
375
373
|
Union[cv.AbstractControlValues, Sequence[Union[int, Collection[int]]]]
|
|
376
374
|
] = None,
|
|
377
|
-
) ->
|
|
375
|
+
) -> cirq.Operation:
|
|
378
376
|
if len(control_qubits) == 0:
|
|
379
377
|
return self
|
|
380
378
|
qubits = tuple(control_qubits)
|
cirq/ops/gateset.py
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
"""Functionality for grouping and validating Cirq gates."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from typing import (
|
|
18
20
|
Any,
|
|
19
21
|
Callable,
|
|
@@ -37,7 +39,7 @@ if TYPE_CHECKING:
|
|
|
37
39
|
|
|
38
40
|
|
|
39
41
|
def _gate_str(
|
|
40
|
-
gate: Union[raw_types.Gate, Type[raw_types.Gate],
|
|
42
|
+
gate: Union[raw_types.Gate, Type[raw_types.Gate], cirq.GateFamily],
|
|
41
43
|
gettr: Callable[[Any], str] = str,
|
|
42
44
|
) -> str:
|
|
43
45
|
return gettr(gate) if not isinstance(gate, type) else f'{gate.__module__}.{gate.__name__}'
|
|
@@ -291,7 +293,7 @@ class GateFamily:
|
|
|
291
293
|
tags_to_accept=(),
|
|
292
294
|
tags_to_ignore=(),
|
|
293
295
|
**kwargs,
|
|
294
|
-
) ->
|
|
296
|
+
) -> GateFamily:
|
|
295
297
|
if isinstance(gate, str):
|
|
296
298
|
gate = protocols.cirq_type_from_json(gate)
|
|
297
299
|
return cls(
|
|
@@ -370,7 +372,7 @@ class Gateset:
|
|
|
370
372
|
|
|
371
373
|
def with_params(
|
|
372
374
|
self, *, name: Optional[str] = None, unroll_circuit_op: Optional[bool] = None
|
|
373
|
-
) ->
|
|
375
|
+
) -> Gateset:
|
|
374
376
|
"""Returns a copy of this Gateset with identical gates and new values for named arguments.
|
|
375
377
|
|
|
376
378
|
If a named argument is None then corresponding value of this Gateset is used instead.
|
|
@@ -445,7 +447,7 @@ class Gateset:
|
|
|
445
447
|
|
|
446
448
|
return any(item in gate_family for gate_family in self._gates)
|
|
447
449
|
|
|
448
|
-
def validate(self, circuit_or_optree: Union[
|
|
450
|
+
def validate(self, circuit_or_optree: Union[cirq.AbstractCircuit, op_tree.OP_TREE]) -> bool:
|
|
449
451
|
"""Validates gates forming `circuit_or_optree` should be contained in Gateset.
|
|
450
452
|
|
|
451
453
|
Args:
|
|
@@ -518,7 +520,7 @@ class Gateset:
|
|
|
518
520
|
}
|
|
519
521
|
|
|
520
522
|
@classmethod
|
|
521
|
-
def _from_json_dict_(cls, gates, name, unroll_circuit_op, **kwargs) ->
|
|
523
|
+
def _from_json_dict_(cls, gates, name, unroll_circuit_op, **kwargs) -> Gateset:
|
|
522
524
|
# This parameter was deprecated in 0.16, but we keep this logic here for backwards
|
|
523
525
|
# compatibility.
|
|
524
526
|
if 'accept_global_phase_op' in kwargs:
|
cirq/ops/global_phase_op.py
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""A no-qubit global phase operation."""
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
from types import NotImplementedType
|
|
17
19
|
from typing import AbstractSet, Any, cast, Collection, Dict, Optional, Sequence, Tuple, Union
|
|
18
20
|
|
|
@@ -27,14 +29,14 @@ from cirq.ops import control_values as cv, controlled_gate, raw_types
|
|
|
27
29
|
|
|
28
30
|
@value.value_equality(approximate=True)
|
|
29
31
|
class GlobalPhaseGate(raw_types.Gate):
|
|
30
|
-
def __init__(self, coefficient:
|
|
32
|
+
def __init__(self, coefficient: cirq.TParamValComplex, atol: float = 1e-8) -> None:
|
|
31
33
|
if not isinstance(coefficient, sympy.Basic):
|
|
32
34
|
if abs(1 - abs(coefficient)) > atol:
|
|
33
35
|
raise ValueError(f'Coefficient is not unitary: {coefficient!r}')
|
|
34
36
|
self._coefficient = coefficient
|
|
35
37
|
|
|
36
38
|
@property
|
|
37
|
-
def coefficient(self) ->
|
|
39
|
+
def coefficient(self) -> cirq.TParamValComplex:
|
|
38
40
|
return self._coefficient
|
|
39
41
|
|
|
40
42
|
def _value_equality_values_(self) -> Any:
|
|
@@ -43,7 +45,7 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
43
45
|
def _has_unitary_(self) -> bool:
|
|
44
46
|
return not self._is_parameterized_()
|
|
45
47
|
|
|
46
|
-
def __pow__(self, power) ->
|
|
48
|
+
def __pow__(self, power) -> cirq.GlobalPhaseGate:
|
|
47
49
|
if isinstance(power, (int, float)):
|
|
48
50
|
return GlobalPhaseGate(self.coefficient**power)
|
|
49
51
|
return NotImplemented
|
|
@@ -53,9 +55,7 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
53
55
|
return NotImplemented
|
|
54
56
|
return np.array([[self.coefficient]])
|
|
55
57
|
|
|
56
|
-
def _apply_unitary_(
|
|
57
|
-
self, args: 'cirq.ApplyUnitaryArgs'
|
|
58
|
-
) -> Union[np.ndarray, NotImplementedType]:
|
|
58
|
+
def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs) -> Union[np.ndarray, NotImplementedType]:
|
|
59
59
|
if not self._has_unitary_():
|
|
60
60
|
return NotImplemented
|
|
61
61
|
assert not cirq.is_parameterized(self)
|
|
@@ -71,7 +71,7 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
71
71
|
def __repr__(self) -> str:
|
|
72
72
|
return f'cirq.GlobalPhaseGate({proper_repr(self.coefficient)})'
|
|
73
73
|
|
|
74
|
-
def _op_repr_(self, qubits: Sequence[
|
|
74
|
+
def _op_repr_(self, qubits: Sequence[cirq.Qid]) -> str:
|
|
75
75
|
return f'cirq.global_phase_operation({proper_repr(self.coefficient)})'
|
|
76
76
|
|
|
77
77
|
def _json_dict_(self) -> Dict[str, Any]:
|
|
@@ -87,8 +87,8 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
87
87
|
return protocols.parameter_names(self.coefficient)
|
|
88
88
|
|
|
89
89
|
def _resolve_parameters_(
|
|
90
|
-
self, resolver:
|
|
91
|
-
) ->
|
|
90
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
91
|
+
) -> cirq.GlobalPhaseGate:
|
|
92
92
|
coefficient = protocols.resolve_parameters(self.coefficient, resolver, recursive)
|
|
93
93
|
return GlobalPhaseGate(coefficient=coefficient)
|
|
94
94
|
|
|
@@ -120,7 +120,7 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
120
120
|
|
|
121
121
|
|
|
122
122
|
def global_phase_operation(
|
|
123
|
-
coefficient:
|
|
124
|
-
) ->
|
|
123
|
+
coefficient: cirq.TParamValComplex, atol: float = 1e-8
|
|
124
|
+
) -> cirq.GateOperation:
|
|
125
125
|
"""Creates an operation that represents a global phase on the state."""
|
|
126
126
|
return GlobalPhaseGate(coefficient, atol)()
|
cirq/ops/greedy_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
|
from typing import Iterable, List, Set, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
from cirq.ops import named_qubit, qid_util, qubit_manager
|
|
@@ -49,25 +51,25 @@ class GreedyQubitManager(qubit_manager.QubitManager):
|
|
|
49
51
|
maximize_reuse: Flag to control a FIFO vs LIFO strategy, defaults to False (FIFO).
|
|
50
52
|
"""
|
|
51
53
|
self._prefix = prefix
|
|
52
|
-
self._used_qubits: Set[
|
|
53
|
-
self._free_qubits: List[
|
|
54
|
+
self._used_qubits: Set[cirq.Qid] = set()
|
|
55
|
+
self._free_qubits: List[cirq.Qid] = []
|
|
54
56
|
self._size = 0
|
|
55
57
|
self.maximize_reuse = maximize_reuse
|
|
56
58
|
self.resize(size)
|
|
57
59
|
|
|
58
|
-
def _allocate_qid(self, name: str, dim: int) ->
|
|
60
|
+
def _allocate_qid(self, name: str, dim: int) -> cirq.Qid:
|
|
59
61
|
return qid_util.q(name) if dim == 2 else named_qubit.NamedQid(name, dimension=dim)
|
|
60
62
|
|
|
61
63
|
def resize(self, new_size: int, dim: int = 2) -> None:
|
|
62
64
|
if new_size <= self._size:
|
|
63
65
|
return
|
|
64
|
-
new_qubits: List[
|
|
66
|
+
new_qubits: List[cirq.Qid] = [
|
|
65
67
|
self._allocate_qid(f'{self._prefix}_{s}', dim) for s in range(self._size, new_size)
|
|
66
68
|
]
|
|
67
69
|
self._free_qubits = new_qubits + self._free_qubits
|
|
68
70
|
self._size = new_size
|
|
69
71
|
|
|
70
|
-
def qalloc(self, n: int, dim: int = 2) -> List[
|
|
72
|
+
def qalloc(self, n: int, dim: int = 2) -> List[cirq.Qid]:
|
|
71
73
|
if not n:
|
|
72
74
|
return []
|
|
73
75
|
self.resize(self._size + n - len(self._free_qubits), dim=dim)
|
|
@@ -76,11 +78,11 @@ class GreedyQubitManager(qubit_manager.QubitManager):
|
|
|
76
78
|
self._used_qubits.update(ret_qubits)
|
|
77
79
|
return ret_qubits
|
|
78
80
|
|
|
79
|
-
def qfree(self, qubits: Iterable[
|
|
81
|
+
def qfree(self, qubits: Iterable[cirq.Qid]) -> None:
|
|
80
82
|
qs = list(dict(zip(qubits, qubits)).keys())
|
|
81
83
|
assert self._used_qubits.issuperset(qs), "Only managed qubits currently in-use can be freed"
|
|
82
84
|
self._used_qubits = self._used_qubits.difference(qs)
|
|
83
85
|
self._free_qubits.extend(qs)
|
|
84
86
|
|
|
85
|
-
def qborrow(self, n: int, dim: int = 2) -> List[
|
|
87
|
+
def qborrow(self, n: int, dim: int = 2) -> List[cirq.Qid]:
|
|
86
88
|
return self.qalloc(n, dim)
|
cirq/ops/identity.py
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""IdentityGate."""
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
import numbers
|
|
17
19
|
from types import NotImplementedType
|
|
18
20
|
from typing import Any, Dict, Optional, Sequence, Tuple, TYPE_CHECKING, Union
|
|
@@ -63,7 +65,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
63
65
|
if len(self._qid_shape) != num_qubits:
|
|
64
66
|
raise ValueError('len(qid_shape) != num_qubits')
|
|
65
67
|
|
|
66
|
-
def _act_on_(self, sim_state:
|
|
68
|
+
def _act_on_(self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]):
|
|
67
69
|
return True
|
|
68
70
|
|
|
69
71
|
def _qid_shape_(self) -> Tuple[int, ...]:
|
|
@@ -89,7 +91,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
89
91
|
def _unitary_(self) -> np.ndarray:
|
|
90
92
|
return np.identity(np.prod(self._qid_shape, dtype=np.int64).item())
|
|
91
93
|
|
|
92
|
-
def _apply_unitary_(self, args:
|
|
94
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> Optional[np.ndarray]:
|
|
93
95
|
return args.target_tensor
|
|
94
96
|
|
|
95
97
|
def _pauli_expansion_(self) -> value.LinearDict[str]:
|
|
@@ -104,7 +106,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
104
106
|
return f'cirq.IdentityGate({len(self._qid_shape)})'
|
|
105
107
|
return f'cirq.IdentityGate(qid_shape={self._qid_shape!r})'
|
|
106
108
|
|
|
107
|
-
def _decompose_(self, qubits) ->
|
|
109
|
+
def _decompose_(self, qubits) -> cirq.OP_TREE:
|
|
108
110
|
return []
|
|
109
111
|
|
|
110
112
|
def __str__(self) -> str:
|
|
@@ -124,7 +126,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
124
126
|
other['qid_shape'] = self._qid_shape
|
|
125
127
|
return {'num_qubits': len(self._qid_shape), **other}
|
|
126
128
|
|
|
127
|
-
def _mul_with_qubits(self, qubits: Tuple[
|
|
129
|
+
def _mul_with_qubits(self, qubits: Tuple[cirq.Qid, ...], other):
|
|
128
130
|
if isinstance(other, raw_types.Operation):
|
|
129
131
|
return other
|
|
130
132
|
if isinstance(other, numbers.Complex):
|
|
@@ -140,7 +142,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
140
142
|
return NotImplemented
|
|
141
143
|
return ('I',) * self.num_qubits()
|
|
142
144
|
|
|
143
|
-
def _qasm_(self, args:
|
|
145
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: Tuple[cirq.Qid, ...]) -> Optional[str]:
|
|
144
146
|
args.validate_version('2.0', '3.0')
|
|
145
147
|
return ''.join([args.format('id {0};\n', qubit) for qubit in qubits])
|
|
146
148
|
|
|
@@ -163,7 +165,7 @@ document(
|
|
|
163
165
|
)
|
|
164
166
|
|
|
165
167
|
|
|
166
|
-
def identity_each(*qubits:
|
|
168
|
+
def identity_each(*qubits: cirq.Qid) -> cirq.Operation:
|
|
167
169
|
"""Returns a single IdentityGate applied to all the given qubits.
|
|
168
170
|
|
|
169
171
|
Args:
|
cirq/ops/kraus_channel.py
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# pylint: disable=wrong-or-nonexistent-copyright-notice
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
2
5
|
from typing import Any, Dict, FrozenSet, Iterable, Mapping, Tuple, TYPE_CHECKING, Union
|
|
3
6
|
|
|
4
7
|
import numpy as np
|
|
@@ -29,7 +32,7 @@ class KrausChannel(raw_types.Gate):
|
|
|
29
32
|
def __init__(
|
|
30
33
|
self,
|
|
31
34
|
kraus_ops: Iterable[np.ndarray],
|
|
32
|
-
key: Union[str,
|
|
35
|
+
key: Union[str, cirq.MeasurementKey, None] = None,
|
|
33
36
|
validate: bool = False,
|
|
34
37
|
):
|
|
35
38
|
kraus_ops = list(kraus_ops)
|
|
@@ -56,7 +59,7 @@ class KrausChannel(raw_types.Gate):
|
|
|
56
59
|
self._key = key
|
|
57
60
|
|
|
58
61
|
@staticmethod
|
|
59
|
-
def from_channel(channel:
|
|
62
|
+
def from_channel(channel: cirq.Gate, key: Union[str, cirq.MeasurementKey, None] = None):
|
|
60
63
|
"""Creates a copy of a channel with the given measurement key."""
|
|
61
64
|
return KrausChannel(kraus_ops=list(protocols.kraus(channel)), key=key)
|
|
62
65
|
|
|
@@ -80,7 +83,7 @@ class KrausChannel(raw_types.Gate):
|
|
|
80
83
|
return NotImplemented
|
|
81
84
|
return str(self._key)
|
|
82
85
|
|
|
83
|
-
def _measurement_key_obj_(self) ->
|
|
86
|
+
def _measurement_key_obj_(self) -> cirq.MeasurementKey:
|
|
84
87
|
if self._key is None:
|
|
85
88
|
return NotImplemented
|
|
86
89
|
return self._key
|
|
@@ -101,7 +104,7 @@ class KrausChannel(raw_types.Gate):
|
|
|
101
104
|
)
|
|
102
105
|
|
|
103
106
|
def _with_rescoped_keys_(
|
|
104
|
-
self, path: Tuple[str, ...], bindable_keys: FrozenSet[
|
|
107
|
+
self, path: Tuple[str, ...], bindable_keys: FrozenSet[cirq.MeasurementKey]
|
|
105
108
|
):
|
|
106
109
|
return KrausChannel(
|
|
107
110
|
kraus_ops=self._kraus_ops,
|