cirq-core 1.5.0.dev20250403170622__py3-none-any.whl → 1.5.0.dev20250404021339__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/circuits/circuit.py +144 -147
- cirq/circuits/circuit_operation.py +37 -34
- cirq/circuits/circuit_operation_test.py +1 -1
- cirq/circuits/circuit_test.py +4 -6
- cirq/circuits/frozen_circuit.py +30 -26
- cirq/circuits/moment.py +37 -37
- cirq/circuits/optimization_pass.py +11 -11
- cirq/circuits/optimization_pass_test.py +6 -8
- cirq/circuits/qasm_output.py +13 -11
- cirq/circuits/text_diagram_drawer.py +9 -7
- cirq/contrib/acquaintance/bipartite.py +7 -5
- cirq/contrib/acquaintance/devices.py +3 -1
- cirq/contrib/acquaintance/executor.py +14 -16
- cirq/contrib/acquaintance/gates.py +19 -21
- cirq/contrib/acquaintance/inspection_utils.py +8 -6
- cirq/contrib/acquaintance/mutation_utils.py +8 -6
- cirq/contrib/acquaintance/optimizers.py +5 -3
- cirq/contrib/acquaintance/permutation.py +19 -19
- cirq/contrib/acquaintance/shift.py +5 -3
- cirq/contrib/acquaintance/shift_swap_network.py +5 -3
- cirq/contrib/acquaintance/strategies/complete.py +4 -2
- cirq/contrib/acquaintance/strategies/cubic.py +4 -2
- cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
- cirq/contrib/acquaintance/topological_sort.py +4 -2
- cirq/contrib/bayesian_network/bayesian_network_gate.py +4 -2
- cirq/contrib/circuitdag/circuit_dag.py +18 -16
- cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +9 -7
- cirq/contrib/graph_device/graph_device.py +4 -2
- cirq/contrib/noise_models/noise_models.py +7 -5
- cirq/contrib/paulistring/clifford_target_gateset.py +11 -9
- cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
- cirq/contrib/quantum_volume/quantum_volume.py +4 -4
- cirq/contrib/quimb/mps_simulator.py +25 -26
- cirq/contrib/routing/greedy.py +5 -3
- cirq/contrib/routing/initialization.py +3 -1
- cirq/contrib/routing/swap_network.py +5 -5
- cirq/contrib/routing/utils.py +4 -2
- cirq/contrib/svg/svg.py +9 -6
- cirq/devices/device.py +11 -9
- cirq/devices/grid_device_metadata.py +14 -11
- cirq/devices/grid_qubit.py +17 -21
- cirq/devices/grid_qubit_test.py +1 -1
- cirq/devices/insertion_noise_model.py +5 -5
- cirq/devices/line_qubit.py +15 -17
- cirq/devices/named_topologies.py +6 -4
- cirq/devices/noise_model.py +27 -31
- {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/METADATA +1 -1
- {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/RECORD +54 -54
- {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/WHEEL +0 -0
- {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/top_level.txt +0 -0
cirq/circuits/circuit.py
CHANGED
|
@@ -19,6 +19,8 @@ Operations. Each Operation is a Gate that acts on some Qubits, for a given
|
|
|
19
19
|
Moment the Operations must all act on distinct Qubits.
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
22
24
|
import abc
|
|
23
25
|
import enum
|
|
24
26
|
import html
|
|
@@ -146,7 +148,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
146
148
|
"""
|
|
147
149
|
|
|
148
150
|
@classmethod
|
|
149
|
-
def from_moments(cls: Type[CIRCUIT_TYPE], *moments: Optional[
|
|
151
|
+
def from_moments(cls: Type[CIRCUIT_TYPE], *moments: Optional[cirq.OP_TREE]) -> CIRCUIT_TYPE:
|
|
150
152
|
"""Create a circuit from moment op trees.
|
|
151
153
|
|
|
152
154
|
Args:
|
|
@@ -164,7 +166,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
164
166
|
return cls._from_moments(cls._make_moments(moments))
|
|
165
167
|
|
|
166
168
|
@staticmethod
|
|
167
|
-
def _make_moments(moments: Iterable[Optional[
|
|
169
|
+
def _make_moments(moments: Iterable[Optional[cirq.OP_TREE]]) -> Iterator[cirq.Moment]:
|
|
168
170
|
for m in moments:
|
|
169
171
|
if isinstance(m, Moment):
|
|
170
172
|
yield m
|
|
@@ -175,7 +177,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
175
177
|
|
|
176
178
|
@classmethod
|
|
177
179
|
@abc.abstractmethod
|
|
178
|
-
def _from_moments(cls: Type[CIRCUIT_TYPE], moments: Iterable[
|
|
180
|
+
def _from_moments(cls: Type[CIRCUIT_TYPE], moments: Iterable[cirq.Moment]) -> CIRCUIT_TYPE:
|
|
179
181
|
"""Create a circuit from moments.
|
|
180
182
|
|
|
181
183
|
This must be implemented by subclasses. It provides a more efficient way
|
|
@@ -188,18 +190,18 @@ class AbstractCircuit(abc.ABC):
|
|
|
188
190
|
|
|
189
191
|
@property
|
|
190
192
|
@abc.abstractmethod
|
|
191
|
-
def moments(self) -> Sequence[
|
|
193
|
+
def moments(self) -> Sequence[cirq.Moment]:
|
|
192
194
|
pass
|
|
193
195
|
|
|
194
196
|
@abc.abstractmethod
|
|
195
|
-
def freeze(self) ->
|
|
197
|
+
def freeze(self) -> cirq.FrozenCircuit:
|
|
196
198
|
"""Creates a FrozenCircuit from this circuit.
|
|
197
199
|
|
|
198
200
|
If 'self' is a FrozenCircuit, the original object is returned.
|
|
199
201
|
"""
|
|
200
202
|
|
|
201
203
|
@abc.abstractmethod
|
|
202
|
-
def unfreeze(self, copy: bool = True) ->
|
|
204
|
+
def unfreeze(self, copy: bool = True) -> cirq.Circuit:
|
|
203
205
|
"""Creates a Circuit from this circuit.
|
|
204
206
|
|
|
205
207
|
Args:
|
|
@@ -231,24 +233,24 @@ class AbstractCircuit(abc.ABC):
|
|
|
231
233
|
def __len__(self) -> int:
|
|
232
234
|
return len(self.moments)
|
|
233
235
|
|
|
234
|
-
def __iter__(self) -> Iterator[
|
|
236
|
+
def __iter__(self) -> Iterator[cirq.Moment]:
|
|
235
237
|
return iter(self.moments)
|
|
236
238
|
|
|
237
|
-
def _decompose_(self) ->
|
|
239
|
+
def _decompose_(self) -> cirq.OP_TREE:
|
|
238
240
|
"""See `cirq.SupportsDecompose`."""
|
|
239
241
|
return self.all_operations()
|
|
240
242
|
|
|
241
243
|
# pylint: disable=function-redefined
|
|
242
244
|
@overload
|
|
243
|
-
def __getitem__(self, key: int) ->
|
|
245
|
+
def __getitem__(self, key: int) -> cirq.Moment:
|
|
244
246
|
pass
|
|
245
247
|
|
|
246
248
|
@overload
|
|
247
|
-
def __getitem__(self, key: Tuple[int,
|
|
249
|
+
def __getitem__(self, key: Tuple[int, cirq.Qid]) -> cirq.Operation:
|
|
248
250
|
pass
|
|
249
251
|
|
|
250
252
|
@overload
|
|
251
|
-
def __getitem__(self, key: Tuple[int, Iterable[
|
|
253
|
+
def __getitem__(self, key: Tuple[int, Iterable[cirq.Qid]]) -> cirq.Moment:
|
|
252
254
|
pass
|
|
253
255
|
|
|
254
256
|
@overload
|
|
@@ -256,11 +258,11 @@ class AbstractCircuit(abc.ABC):
|
|
|
256
258
|
pass
|
|
257
259
|
|
|
258
260
|
@overload
|
|
259
|
-
def __getitem__(self, key: Tuple[slice,
|
|
261
|
+
def __getitem__(self, key: Tuple[slice, cirq.Qid]) -> Self:
|
|
260
262
|
pass
|
|
261
263
|
|
|
262
264
|
@overload
|
|
263
|
-
def __getitem__(self, key: Tuple[slice, Iterable[
|
|
265
|
+
def __getitem__(self, key: Tuple[slice, Iterable[cirq.Qid]]) -> Self:
|
|
264
266
|
pass
|
|
265
267
|
|
|
266
268
|
def __getitem__(self, key):
|
|
@@ -315,7 +317,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
315
317
|
)
|
|
316
318
|
|
|
317
319
|
def _first_moment_operating_on(
|
|
318
|
-
self, qubits: Iterable[
|
|
320
|
+
self, qubits: Iterable[cirq.Qid], indices: Iterable[int]
|
|
319
321
|
) -> Optional[int]:
|
|
320
322
|
qubits = frozenset(qubits)
|
|
321
323
|
for m in indices:
|
|
@@ -325,7 +327,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
325
327
|
|
|
326
328
|
def next_moment_operating_on(
|
|
327
329
|
self,
|
|
328
|
-
qubits: Iterable[
|
|
330
|
+
qubits: Iterable[cirq.Qid],
|
|
329
331
|
start_moment_index: int = 0,
|
|
330
332
|
max_distance: Optional[int] = None,
|
|
331
333
|
) -> Optional[int]:
|
|
@@ -357,8 +359,8 @@ class AbstractCircuit(abc.ABC):
|
|
|
357
359
|
)
|
|
358
360
|
|
|
359
361
|
def next_moments_operating_on(
|
|
360
|
-
self, qubits: Iterable[
|
|
361
|
-
) -> Dict[
|
|
362
|
+
self, qubits: Iterable[cirq.Qid], start_moment_index: int = 0
|
|
363
|
+
) -> Dict[cirq.Qid, int]:
|
|
362
364
|
"""Finds the index of the next moment that touches each qubit.
|
|
363
365
|
|
|
364
366
|
Args:
|
|
@@ -380,7 +382,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
380
382
|
|
|
381
383
|
def prev_moment_operating_on(
|
|
382
384
|
self,
|
|
383
|
-
qubits: Sequence[
|
|
385
|
+
qubits: Sequence[cirq.Qid],
|
|
384
386
|
end_moment_index: Optional[int] = None,
|
|
385
387
|
max_distance: Optional[int] = None,
|
|
386
388
|
) -> Optional[int]:
|
|
@@ -425,10 +427,10 @@ class AbstractCircuit(abc.ABC):
|
|
|
425
427
|
|
|
426
428
|
def reachable_frontier_from(
|
|
427
429
|
self,
|
|
428
|
-
start_frontier: Dict[
|
|
430
|
+
start_frontier: Dict[cirq.Qid, int],
|
|
429
431
|
*,
|
|
430
|
-
is_blocker: Callable[[
|
|
431
|
-
) -> Dict[
|
|
432
|
+
is_blocker: Callable[[cirq.Operation], bool] = lambda op: False,
|
|
433
|
+
) -> Dict[cirq.Qid, int]:
|
|
432
434
|
"""Determines how far can be reached into a circuit under certain rules.
|
|
433
435
|
|
|
434
436
|
The location L = (qubit, moment_index) is *reachable* if and only if the
|
|
@@ -564,11 +566,11 @@ class AbstractCircuit(abc.ABC):
|
|
|
564
566
|
where i is the moment index, q is the qubit, and end_frontier is the
|
|
565
567
|
result of this method.
|
|
566
568
|
"""
|
|
567
|
-
active: Set[
|
|
569
|
+
active: Set[cirq.Qid] = set()
|
|
568
570
|
end_frontier = {}
|
|
569
571
|
queue = BucketPriorityQueue[ops.Operation](drop_duplicate_entries=True)
|
|
570
572
|
|
|
571
|
-
def enqueue_next(qubit:
|
|
573
|
+
def enqueue_next(qubit: cirq.Qid, moment: int) -> None:
|
|
572
574
|
next_moment = self.next_moment_operating_on([qubit], moment)
|
|
573
575
|
if next_moment is None:
|
|
574
576
|
end_frontier[qubit] = max(len(self), start_frontier[qubit])
|
|
@@ -608,10 +610,10 @@ class AbstractCircuit(abc.ABC):
|
|
|
608
610
|
|
|
609
611
|
def findall_operations_between(
|
|
610
612
|
self,
|
|
611
|
-
start_frontier: Dict[
|
|
612
|
-
end_frontier: Dict[
|
|
613
|
+
start_frontier: Dict[cirq.Qid, int],
|
|
614
|
+
end_frontier: Dict[cirq.Qid, int],
|
|
613
615
|
omit_crossing_operations: bool = False,
|
|
614
|
-
) -> List[Tuple[int,
|
|
616
|
+
) -> List[Tuple[int, cirq.Operation]]:
|
|
615
617
|
"""Finds operations between the two given frontiers.
|
|
616
618
|
|
|
617
619
|
If a qubit is in `start_frontier` but not `end_frontier`, its end index
|
|
@@ -656,9 +658,9 @@ class AbstractCircuit(abc.ABC):
|
|
|
656
658
|
|
|
657
659
|
def findall_operations_until_blocked(
|
|
658
660
|
self,
|
|
659
|
-
start_frontier: Dict[
|
|
660
|
-
is_blocker: Callable[[
|
|
661
|
-
) -> List[Tuple[int,
|
|
661
|
+
start_frontier: Dict[cirq.Qid, int],
|
|
662
|
+
is_blocker: Callable[[cirq.Operation], bool] = lambda op: False,
|
|
663
|
+
) -> List[Tuple[int, cirq.Operation]]:
|
|
662
664
|
"""Finds all operations until a blocking operation is hit.
|
|
663
665
|
|
|
664
666
|
An operation is considered blocking if both of the following hold:
|
|
@@ -760,7 +762,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
760
762
|
break
|
|
761
763
|
return op_list
|
|
762
764
|
|
|
763
|
-
def operation_at(self, qubit:
|
|
765
|
+
def operation_at(self, qubit: cirq.Qid, moment_index: int) -> Optional[cirq.Operation]:
|
|
764
766
|
"""Finds the operation on a qubit within a moment, if any.
|
|
765
767
|
|
|
766
768
|
Args:
|
|
@@ -777,8 +779,8 @@ class AbstractCircuit(abc.ABC):
|
|
|
777
779
|
return self.moments[moment_index].operation_at(qubit)
|
|
778
780
|
|
|
779
781
|
def findall_operations(
|
|
780
|
-
self, predicate: Callable[[
|
|
781
|
-
) -> Iterable[Tuple[int,
|
|
782
|
+
self, predicate: Callable[[cirq.Operation], bool]
|
|
783
|
+
) -> Iterable[Tuple[int, cirq.Operation]]:
|
|
782
784
|
"""Find the locations of all operations that satisfy a given condition.
|
|
783
785
|
|
|
784
786
|
This returns an iterator of (index, operation) tuples where each
|
|
@@ -799,7 +801,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
799
801
|
|
|
800
802
|
def findall_operations_with_gate_type(
|
|
801
803
|
self, gate_type: Type[_TGate]
|
|
802
|
-
) -> Iterable[Tuple[int,
|
|
804
|
+
) -> Iterable[Tuple[int, cirq.GateOperation, _TGate]]:
|
|
803
805
|
"""Find the locations of all gate operations of a given type.
|
|
804
806
|
|
|
805
807
|
Args:
|
|
@@ -832,7 +834,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
832
834
|
"""
|
|
833
835
|
return self.are_all_matches_terminal(protocols.is_measurement)
|
|
834
836
|
|
|
835
|
-
def are_all_matches_terminal(self, predicate: Callable[[
|
|
837
|
+
def are_all_matches_terminal(self, predicate: Callable[[cirq.Operation], bool]) -> bool:
|
|
836
838
|
"""Check whether all of the ops that satisfy a predicate are terminal.
|
|
837
839
|
|
|
838
840
|
This method will transparently descend into any CircuitOperations this
|
|
@@ -877,7 +879,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
877
879
|
"""
|
|
878
880
|
return self.are_any_matches_terminal(protocols.is_measurement)
|
|
879
881
|
|
|
880
|
-
def are_any_matches_terminal(self, predicate: Callable[[
|
|
882
|
+
def are_any_matches_terminal(self, predicate: Callable[[cirq.Operation], bool]) -> bool:
|
|
881
883
|
"""Check whether any of the ops that satisfy a predicate are terminal.
|
|
882
884
|
|
|
883
885
|
This method will transparently descend into any CircuitOperations this
|
|
@@ -915,12 +917,12 @@ class AbstractCircuit(abc.ABC):
|
|
|
915
917
|
return True
|
|
916
918
|
return False
|
|
917
919
|
|
|
918
|
-
def _has_op_at(self, moment_index: int, qubits: Iterable[
|
|
920
|
+
def _has_op_at(self, moment_index: int, qubits: Iterable[cirq.Qid]) -> bool:
|
|
919
921
|
return 0 <= moment_index < len(self.moments) and self.moments[moment_index].operates_on(
|
|
920
922
|
qubits
|
|
921
923
|
)
|
|
922
924
|
|
|
923
|
-
def all_qubits(self) -> FrozenSet[
|
|
925
|
+
def all_qubits(self) -> FrozenSet[cirq.Qid]:
|
|
924
926
|
"""Returns the qubits acted upon by Operations in this circuit.
|
|
925
927
|
|
|
926
928
|
Returns: FrozenSet of `cirq.Qid` objects acted on by all operations
|
|
@@ -928,14 +930,14 @@ class AbstractCircuit(abc.ABC):
|
|
|
928
930
|
"""
|
|
929
931
|
return frozenset(q for m in self.moments for q in m.qubits)
|
|
930
932
|
|
|
931
|
-
def all_operations(self) -> Iterator[
|
|
933
|
+
def all_operations(self) -> Iterator[cirq.Operation]:
|
|
932
934
|
"""Returns an iterator over the operations in the circuit.
|
|
933
935
|
|
|
934
936
|
Returns: Iterator over `cirq.Operation` elements found in this circuit.
|
|
935
937
|
"""
|
|
936
938
|
return (op for moment in self for op in moment.operations)
|
|
937
939
|
|
|
938
|
-
def map_operations(self, func: Callable[[
|
|
940
|
+
def map_operations(self, func: Callable[[cirq.Operation], cirq.OP_TREE]) -> Self:
|
|
939
941
|
"""Applies the given function to all operations in this circuit.
|
|
940
942
|
|
|
941
943
|
Args:
|
|
@@ -946,14 +948,14 @@ class AbstractCircuit(abc.ABC):
|
|
|
946
948
|
each operation `op` replaced with `func(op)`.
|
|
947
949
|
"""
|
|
948
950
|
|
|
949
|
-
def map_moment(moment:
|
|
951
|
+
def map_moment(moment: cirq.Moment) -> cirq.Circuit:
|
|
950
952
|
"""Apply func to expand each op into a circuit, then zip up the circuits."""
|
|
951
953
|
return Circuit.zip(*[Circuit(func(op)) for op in moment])
|
|
952
954
|
|
|
953
955
|
return self._from_moments(m for moment in self for m in map_moment(moment))
|
|
954
956
|
|
|
955
957
|
def qid_shape(
|
|
956
|
-
self, qubit_order:
|
|
958
|
+
self, qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT
|
|
957
959
|
) -> Tuple[int, ...]:
|
|
958
960
|
"""Get the qubit shapes of all qubits in this circuit.
|
|
959
961
|
|
|
@@ -963,12 +965,12 @@ class AbstractCircuit(abc.ABC):
|
|
|
963
965
|
qids = ops.QubitOrder.as_qubit_order(qubit_order).order_for(self.all_qubits())
|
|
964
966
|
return protocols.qid_shape(qids)
|
|
965
967
|
|
|
966
|
-
def all_measurement_key_objs(self) -> FrozenSet[
|
|
968
|
+
def all_measurement_key_objs(self) -> FrozenSet[cirq.MeasurementKey]:
|
|
967
969
|
return frozenset(
|
|
968
970
|
key for op in self.all_operations() for key in protocols.measurement_key_objs(op)
|
|
969
971
|
)
|
|
970
972
|
|
|
971
|
-
def _measurement_key_objs_(self) -> FrozenSet[
|
|
973
|
+
def _measurement_key_objs_(self) -> FrozenSet[cirq.MeasurementKey]:
|
|
972
974
|
"""Returns the set of all measurement keys in this circuit.
|
|
973
975
|
|
|
974
976
|
Returns: FrozenSet of `cirq.MeasurementKey` objects that are
|
|
@@ -1003,7 +1005,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1003
1005
|
)
|
|
1004
1006
|
|
|
1005
1007
|
def _with_rescoped_keys_(
|
|
1006
|
-
self, path: Tuple[str, ...], bindable_keys: FrozenSet[
|
|
1008
|
+
self, path: Tuple[str, ...], bindable_keys: FrozenSet[cirq.MeasurementKey]
|
|
1007
1009
|
):
|
|
1008
1010
|
moments = []
|
|
1009
1011
|
for moment in self.moments:
|
|
@@ -1042,8 +1044,8 @@ class AbstractCircuit(abc.ABC):
|
|
|
1042
1044
|
|
|
1043
1045
|
def unitary(
|
|
1044
1046
|
self,
|
|
1045
|
-
qubit_order:
|
|
1046
|
-
qubits_that_should_be_present: Iterable[
|
|
1047
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
1048
|
+
qubits_that_should_be_present: Iterable[cirq.Qid] = (),
|
|
1047
1049
|
ignore_terminal_measurements: bool = True,
|
|
1048
1050
|
dtype: Type[np.complexfloating] = np.complex128,
|
|
1049
1051
|
) -> np.ndarray:
|
|
@@ -1119,12 +1121,12 @@ class AbstractCircuit(abc.ABC):
|
|
|
1119
1121
|
def final_state_vector(
|
|
1120
1122
|
self,
|
|
1121
1123
|
*,
|
|
1122
|
-
initial_state:
|
|
1123
|
-
qubit_order:
|
|
1124
|
+
initial_state: cirq.STATE_VECTOR_LIKE = 0,
|
|
1125
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
1124
1126
|
ignore_terminal_measurements: bool = False,
|
|
1125
1127
|
dtype: Type[np.complexfloating] = np.complex128,
|
|
1126
|
-
param_resolver:
|
|
1127
|
-
seed:
|
|
1128
|
+
param_resolver: cirq.ParamResolverOrSimilarType = None,
|
|
1129
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
1128
1130
|
) -> np.ndarray:
|
|
1129
1131
|
"""Returns the state vector resulting from acting operations on a state.
|
|
1130
1132
|
|
|
@@ -1182,7 +1184,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1182
1184
|
transpose: bool = False,
|
|
1183
1185
|
include_tags: bool = True,
|
|
1184
1186
|
precision: Optional[int] = 3,
|
|
1185
|
-
qubit_order:
|
|
1187
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
1186
1188
|
) -> str:
|
|
1187
1189
|
"""Returns text containing a diagram describing the circuit.
|
|
1188
1190
|
|
|
@@ -1215,16 +1217,16 @@ class AbstractCircuit(abc.ABC):
|
|
|
1215
1217
|
self,
|
|
1216
1218
|
*,
|
|
1217
1219
|
use_unicode_characters: bool = True,
|
|
1218
|
-
qubit_namer: Optional[Callable[[
|
|
1220
|
+
qubit_namer: Optional[Callable[[cirq.Qid], str]] = None,
|
|
1219
1221
|
transpose: bool = False,
|
|
1220
1222
|
include_tags: bool = True,
|
|
1221
1223
|
draw_moment_groups: bool = True,
|
|
1222
1224
|
precision: Optional[int] = 3,
|
|
1223
|
-
qubit_order:
|
|
1225
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
1224
1226
|
get_circuit_diagram_info: Optional[
|
|
1225
|
-
Callable[[
|
|
1227
|
+
Callable[[cirq.Operation, cirq.CircuitDiagramInfoArgs], cirq.CircuitDiagramInfo]
|
|
1226
1228
|
] = None,
|
|
1227
|
-
) ->
|
|
1229
|
+
) -> cirq.TextDiagramDrawer:
|
|
1228
1230
|
"""Returns a TextDiagramDrawer with the circuit drawn into it.
|
|
1229
1231
|
|
|
1230
1232
|
Args:
|
|
@@ -1307,9 +1309,9 @@ class AbstractCircuit(abc.ABC):
|
|
|
1307
1309
|
def _parameter_names_(self) -> AbstractSet[str]:
|
|
1308
1310
|
return {name for op in self.all_operations() for name in protocols.parameter_names(op)}
|
|
1309
1311
|
|
|
1310
|
-
def _resolve_parameters_(self, resolver:
|
|
1312
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> Self:
|
|
1311
1313
|
changed = False
|
|
1312
|
-
resolved_moments: List[
|
|
1314
|
+
resolved_moments: List[cirq.Moment] = []
|
|
1313
1315
|
for moment in self:
|
|
1314
1316
|
resolved_moment = protocols.resolve_parameters(moment, resolver, recursive)
|
|
1315
1317
|
if resolved_moment is not moment:
|
|
@@ -1319,7 +1321,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1319
1321
|
return self # pragma: no cover
|
|
1320
1322
|
return self._from_moments(resolved_moments)
|
|
1321
1323
|
|
|
1322
|
-
def _qasm_(self, args: Optional[
|
|
1324
|
+
def _qasm_(self, args: Optional[cirq.QasmArgs] = None) -> str:
|
|
1323
1325
|
if args is None:
|
|
1324
1326
|
output = self._to_qasm_output()
|
|
1325
1327
|
else:
|
|
@@ -1330,9 +1332,9 @@ class AbstractCircuit(abc.ABC):
|
|
|
1330
1332
|
self,
|
|
1331
1333
|
header: Optional[str] = None,
|
|
1332
1334
|
precision: int = 10,
|
|
1333
|
-
qubit_order:
|
|
1335
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
1334
1336
|
version: str = '2.0',
|
|
1335
|
-
) ->
|
|
1337
|
+
) -> cirq.QasmOutput:
|
|
1336
1338
|
"""Returns a QASM object equivalent to the circuit.
|
|
1337
1339
|
|
|
1338
1340
|
Args:
|
|
@@ -1359,7 +1361,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1359
1361
|
self,
|
|
1360
1362
|
header: Optional[str] = None,
|
|
1361
1363
|
precision: int = 10,
|
|
1362
|
-
qubit_order:
|
|
1364
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
1363
1365
|
version: str = '2.0',
|
|
1364
1366
|
) -> str:
|
|
1365
1367
|
"""Returns QASM equivalent to the circuit.
|
|
@@ -1381,7 +1383,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1381
1383
|
file_path: Union[str, bytes, int],
|
|
1382
1384
|
header: Optional[str] = None,
|
|
1383
1385
|
precision: int = 10,
|
|
1384
|
-
qubit_order:
|
|
1386
|
+
qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT,
|
|
1385
1387
|
) -> None:
|
|
1386
1388
|
"""Save a QASM file equivalent to the circuit.
|
|
1387
1389
|
|
|
@@ -1403,8 +1405,8 @@ class AbstractCircuit(abc.ABC):
|
|
|
1403
1405
|
return cls(moments, strategy=InsertStrategy.EARLIEST)
|
|
1404
1406
|
|
|
1405
1407
|
def zip(
|
|
1406
|
-
*circuits:
|
|
1407
|
-
) ->
|
|
1408
|
+
*circuits: cirq.AbstractCircuit, align: Union[cirq.Alignment, str] = Alignment.LEFT
|
|
1409
|
+
) -> cirq.AbstractCircuit:
|
|
1408
1410
|
"""Combines operations from circuits in a moment-by-moment fashion.
|
|
1409
1411
|
|
|
1410
1412
|
Moment k of the resulting circuit will have all operations from moment
|
|
@@ -1479,8 +1481,8 @@ class AbstractCircuit(abc.ABC):
|
|
|
1479
1481
|
return result
|
|
1480
1482
|
|
|
1481
1483
|
def concat_ragged(
|
|
1482
|
-
*circuits:
|
|
1483
|
-
) ->
|
|
1484
|
+
*circuits: cirq.AbstractCircuit, align: Union[cirq.Alignment, str] = Alignment.LEFT
|
|
1485
|
+
) -> cirq.AbstractCircuit:
|
|
1484
1486
|
"""Concatenates circuits, overlapping them if possible due to ragged edges.
|
|
1485
1487
|
|
|
1486
1488
|
Starts with the first circuit (index 0), then iterates over the other
|
|
@@ -1523,7 +1525,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1523
1525
|
|
|
1524
1526
|
# Allocate a buffer large enough to append and prepend all the circuits.
|
|
1525
1527
|
pad_len = sum(len(c) for c in circuits) - n_acc
|
|
1526
|
-
buffer: MutableSequence[
|
|
1528
|
+
buffer: MutableSequence[cirq.Moment] = [cirq.Moment()] * (pad_len * 2 + n_acc)
|
|
1527
1529
|
|
|
1528
1530
|
# Put the initial circuit in the center of the buffer.
|
|
1529
1531
|
offset = pad_len
|
|
@@ -1535,7 +1537,7 @@ class AbstractCircuit(abc.ABC):
|
|
|
1535
1537
|
|
|
1536
1538
|
return cirq.Circuit(buffer[offset : offset + n_acc])
|
|
1537
1539
|
|
|
1538
|
-
def get_independent_qubit_sets(self) -> List[Set[
|
|
1540
|
+
def get_independent_qubit_sets(self) -> List[Set[cirq.Qid]]:
|
|
1539
1541
|
"""Divide circuit's qubits into independent qubit sets.
|
|
1540
1542
|
|
|
1541
1543
|
Independent qubit sets are the qubit sets such that there are
|
|
@@ -1614,17 +1616,17 @@ class AbstractCircuit(abc.ABC):
|
|
|
1614
1616
|
# moments.
|
|
1615
1617
|
return (self._from_moments(m[qubits] for m in self.moments) for qubits in qubit_factors)
|
|
1616
1618
|
|
|
1617
|
-
def _control_keys_(self) -> FrozenSet[
|
|
1619
|
+
def _control_keys_(self) -> FrozenSet[cirq.MeasurementKey]:
|
|
1618
1620
|
controls = frozenset(k for op in self.all_operations() for k in protocols.control_keys(op))
|
|
1619
1621
|
return controls - protocols.measurement_key_objs(self)
|
|
1620
1622
|
|
|
1621
1623
|
|
|
1622
1624
|
def _overlap_collision_time(
|
|
1623
|
-
c1: Sequence[
|
|
1625
|
+
c1: Sequence[cirq.Moment], c2: Sequence[cirq.Moment], align: cirq.Alignment
|
|
1624
1626
|
) -> int:
|
|
1625
1627
|
# Tracks the first used moment index for each qubit in c2.
|
|
1626
1628
|
# Tracks the complementary last used moment index for each qubit in c1.
|
|
1627
|
-
seen_times: Dict[
|
|
1629
|
+
seen_times: Dict[cirq.Qid, int] = {}
|
|
1628
1630
|
|
|
1629
1631
|
# Start scanning from end of first and start of second.
|
|
1630
1632
|
if align == Alignment.LEFT:
|
|
@@ -1662,9 +1664,9 @@ def _overlap_collision_time(
|
|
|
1662
1664
|
def _concat_ragged_helper(
|
|
1663
1665
|
c1_offset: int,
|
|
1664
1666
|
n1: int,
|
|
1665
|
-
buf: MutableSequence[
|
|
1666
|
-
c2: Sequence[
|
|
1667
|
-
align:
|
|
1667
|
+
buf: MutableSequence[cirq.Moment],
|
|
1668
|
+
c2: Sequence[cirq.Moment],
|
|
1669
|
+
align: cirq.Alignment,
|
|
1668
1670
|
) -> Tuple[int, int]:
|
|
1669
1671
|
n2 = len(c2)
|
|
1670
1672
|
shift = _overlap_collision_time(buf[c1_offset : c1_offset + n1], c2, align)
|
|
@@ -1755,7 +1757,7 @@ class Circuit(AbstractCircuit):
|
|
|
1755
1757
|
"""
|
|
1756
1758
|
|
|
1757
1759
|
def __init__(
|
|
1758
|
-
self, *contents:
|
|
1760
|
+
self, *contents: cirq.OP_TREE, strategy: cirq.InsertStrategy = InsertStrategy.EARLIEST
|
|
1759
1761
|
) -> None:
|
|
1760
1762
|
"""Initializes a circuit.
|
|
1761
1763
|
|
|
@@ -1771,13 +1773,13 @@ class Circuit(AbstractCircuit):
|
|
|
1771
1773
|
circuit.
|
|
1772
1774
|
"""
|
|
1773
1775
|
self._placement_cache: Optional[_PlacementCache] = _PlacementCache()
|
|
1774
|
-
self._moments: List[
|
|
1776
|
+
self._moments: List[cirq.Moment] = []
|
|
1775
1777
|
|
|
1776
1778
|
# Implementation note: the following cached properties are set lazily and then
|
|
1777
1779
|
# invalidated and reset to None in `self._mutated()`, which is called any time
|
|
1778
1780
|
# `self._moments` is changed.
|
|
1779
|
-
self._all_qubits: Optional[FrozenSet[
|
|
1780
|
-
self._frozen: Optional[
|
|
1781
|
+
self._all_qubits: Optional[FrozenSet[cirq.Qid]] = None
|
|
1782
|
+
self._frozen: Optional[cirq.FrozenCircuit] = None
|
|
1781
1783
|
self._is_measurement: Optional[bool] = None
|
|
1782
1784
|
self._is_parameterized: Optional[bool] = None
|
|
1783
1785
|
self._parameter_names: Optional[AbstractSet[str]] = None
|
|
@@ -1805,13 +1807,13 @@ class Circuit(AbstractCircuit):
|
|
|
1805
1807
|
self._placement_cache = None
|
|
1806
1808
|
|
|
1807
1809
|
@classmethod
|
|
1808
|
-
def _from_moments(cls, moments: Iterable[
|
|
1810
|
+
def _from_moments(cls, moments: Iterable[cirq.Moment]) -> Circuit:
|
|
1809
1811
|
new_circuit = Circuit()
|
|
1810
1812
|
new_circuit._moments[:] = moments
|
|
1811
1813
|
new_circuit._placement_cache = None
|
|
1812
1814
|
return new_circuit
|
|
1813
1815
|
|
|
1814
|
-
def _load_contents_with_earliest_strategy(self, contents:
|
|
1816
|
+
def _load_contents_with_earliest_strategy(self, contents: cirq.OP_TREE):
|
|
1815
1817
|
"""Optimized algorithm to load contents quickly.
|
|
1816
1818
|
|
|
1817
1819
|
The default algorithm appends operations one-at-a-time, letting them
|
|
@@ -1835,8 +1837,8 @@ class Circuit(AbstractCircuit):
|
|
|
1835
1837
|
|
|
1836
1838
|
# We also maintain the dict from moment index to moments/ops that go into it, for use when
|
|
1837
1839
|
# building the actual moments at the end.
|
|
1838
|
-
op_lists_by_index: Dict[int, List[
|
|
1839
|
-
moments_by_index: Dict[int,
|
|
1840
|
+
op_lists_by_index: Dict[int, List[cirq.Operation]] = defaultdict(list)
|
|
1841
|
+
moments_by_index: Dict[int, cirq.Moment] = {}
|
|
1840
1842
|
|
|
1841
1843
|
# "mop" means current moment-or-operation
|
|
1842
1844
|
for mop in ops.flatten_to_ops_or_moments(contents):
|
|
@@ -1855,10 +1857,10 @@ class Circuit(AbstractCircuit):
|
|
|
1855
1857
|
else:
|
|
1856
1858
|
self._moments.append(Moment(op_lists_by_index[i]))
|
|
1857
1859
|
|
|
1858
|
-
def __copy__(self) ->
|
|
1860
|
+
def __copy__(self) -> cirq.Circuit:
|
|
1859
1861
|
return self.copy()
|
|
1860
1862
|
|
|
1861
|
-
def freeze(self) ->
|
|
1863
|
+
def freeze(self) -> cirq.FrozenCircuit:
|
|
1862
1864
|
"""Gets a frozen version of this circuit.
|
|
1863
1865
|
|
|
1864
1866
|
Repeated calls to `.freeze()` will return the same FrozenCircuit
|
|
@@ -1870,10 +1872,10 @@ class Circuit(AbstractCircuit):
|
|
|
1870
1872
|
self._frozen = FrozenCircuit._from_moments(self._moments)
|
|
1871
1873
|
return self._frozen
|
|
1872
1874
|
|
|
1873
|
-
def unfreeze(self, copy: bool = True) ->
|
|
1875
|
+
def unfreeze(self, copy: bool = True) -> cirq.Circuit:
|
|
1874
1876
|
return self.copy() if copy else self
|
|
1875
1877
|
|
|
1876
|
-
def all_qubits(self) -> FrozenSet[
|
|
1878
|
+
def all_qubits(self) -> FrozenSet[cirq.Qid]:
|
|
1877
1879
|
if self._all_qubits is None:
|
|
1878
1880
|
self._all_qubits = super().all_qubits()
|
|
1879
1881
|
return self._all_qubits
|
|
@@ -1893,7 +1895,7 @@ class Circuit(AbstractCircuit):
|
|
|
1893
1895
|
self._parameter_names = super()._parameter_names_()
|
|
1894
1896
|
return self._parameter_names
|
|
1895
1897
|
|
|
1896
|
-
def copy(self) ->
|
|
1898
|
+
def copy(self) -> Circuit:
|
|
1897
1899
|
"""Return a copy of this circuit."""
|
|
1898
1900
|
copied_circuit = Circuit()
|
|
1899
1901
|
copied_circuit._moments = self._moments[:]
|
|
@@ -1902,11 +1904,11 @@ class Circuit(AbstractCircuit):
|
|
|
1902
1904
|
|
|
1903
1905
|
# pylint: disable=function-redefined
|
|
1904
1906
|
@overload
|
|
1905
|
-
def __setitem__(self, key: int, value:
|
|
1907
|
+
def __setitem__(self, key: int, value: cirq.Moment):
|
|
1906
1908
|
pass
|
|
1907
1909
|
|
|
1908
1910
|
@overload
|
|
1909
|
-
def __setitem__(self, key: slice, value: Iterable[
|
|
1911
|
+
def __setitem__(self, key: slice, value: Iterable[cirq.Moment]):
|
|
1910
1912
|
pass
|
|
1911
1913
|
|
|
1912
1914
|
def __setitem__(self, key, value):
|
|
@@ -1967,7 +1969,7 @@ class Circuit(AbstractCircuit):
|
|
|
1967
1969
|
return NotImplemented
|
|
1968
1970
|
return self * int(repetitions)
|
|
1969
1971
|
|
|
1970
|
-
def __pow__(self, exponent: int) ->
|
|
1972
|
+
def __pow__(self, exponent: int) -> cirq.Circuit:
|
|
1971
1973
|
"""A circuit raised to a power, only valid for exponent -1, the inverse.
|
|
1972
1974
|
|
|
1973
1975
|
This will fail if anything other than -1 is passed to the Circuit by
|
|
@@ -1991,22 +1993,22 @@ class Circuit(AbstractCircuit):
|
|
|
1991
1993
|
__hash__ = None # type: ignore
|
|
1992
1994
|
|
|
1993
1995
|
def concat_ragged(
|
|
1994
|
-
*circuits:
|
|
1995
|
-
) ->
|
|
1996
|
+
*circuits: cirq.AbstractCircuit, align: Union[cirq.Alignment, str] = Alignment.LEFT
|
|
1997
|
+
) -> cirq.Circuit:
|
|
1996
1998
|
return AbstractCircuit.concat_ragged(*circuits, align=align).unfreeze(copy=False)
|
|
1997
1999
|
|
|
1998
2000
|
concat_ragged.__doc__ = AbstractCircuit.concat_ragged.__doc__
|
|
1999
2001
|
|
|
2000
2002
|
def zip(
|
|
2001
|
-
*circuits:
|
|
2002
|
-
) ->
|
|
2003
|
+
*circuits: cirq.AbstractCircuit, align: Union[cirq.Alignment, str] = Alignment.LEFT
|
|
2004
|
+
) -> cirq.Circuit:
|
|
2003
2005
|
return AbstractCircuit.zip(*circuits, align=align).unfreeze(copy=False)
|
|
2004
2006
|
|
|
2005
2007
|
zip.__doc__ = AbstractCircuit.zip.__doc__
|
|
2006
2008
|
|
|
2007
2009
|
def transform_qubits(
|
|
2008
|
-
self, qubit_map: Union[Dict[
|
|
2009
|
-
) ->
|
|
2010
|
+
self, qubit_map: Union[Dict[cirq.Qid, cirq.Qid], Callable[[cirq.Qid], cirq.Qid]]
|
|
2011
|
+
) -> cirq.Circuit:
|
|
2010
2012
|
"""Returns the same circuit, but with different qubits.
|
|
2011
2013
|
|
|
2012
2014
|
This function will return a new `Circuit` with the same gates but
|
|
@@ -2053,7 +2055,7 @@ class Circuit(AbstractCircuit):
|
|
|
2053
2055
|
return Circuit(op_list)
|
|
2054
2056
|
|
|
2055
2057
|
def earliest_available_moment(
|
|
2056
|
-
self, op:
|
|
2058
|
+
self, op: cirq.Operation, *, end_moment_index: Optional[int] = None
|
|
2057
2059
|
) -> int:
|
|
2058
2060
|
"""Finds the index of the earliest (i.e. left most) moment which can accommodate `op`.
|
|
2059
2061
|
|
|
@@ -2096,7 +2098,7 @@ class Circuit(AbstractCircuit):
|
|
|
2096
2098
|
last_available = k
|
|
2097
2099
|
return last_available
|
|
2098
2100
|
|
|
2099
|
-
def _can_add_op_at(self, moment_index: int, operation:
|
|
2101
|
+
def _can_add_op_at(self, moment_index: int, operation: cirq.Operation) -> bool:
|
|
2100
2102
|
if not 0 <= moment_index < len(self._moments):
|
|
2101
2103
|
return True
|
|
2102
2104
|
|
|
@@ -2105,8 +2107,8 @@ class Circuit(AbstractCircuit):
|
|
|
2105
2107
|
def insert(
|
|
2106
2108
|
self,
|
|
2107
2109
|
index: int,
|
|
2108
|
-
moment_or_operation_tree:
|
|
2109
|
-
strategy:
|
|
2110
|
+
moment_or_operation_tree: cirq.OP_TREE,
|
|
2111
|
+
strategy: cirq.InsertStrategy = InsertStrategy.EARLIEST,
|
|
2110
2112
|
) -> int:
|
|
2111
2113
|
"""Inserts operations into the circuit.
|
|
2112
2114
|
|
|
@@ -2146,7 +2148,7 @@ class Circuit(AbstractCircuit):
|
|
|
2146
2148
|
and not all(
|
|
2147
2149
|
(strategy is InsertStrategy.EARLIEST and self._can_add_op_at(k, op))
|
|
2148
2150
|
or (k > 0 and self._can_add_op_at(k - 1, op))
|
|
2149
|
-
for op in cast(List[
|
|
2151
|
+
for op in cast(List[cirq.Operation], batch)
|
|
2150
2152
|
)
|
|
2151
2153
|
):
|
|
2152
2154
|
self._moments.insert(k, Moment())
|
|
@@ -2182,7 +2184,7 @@ class Circuit(AbstractCircuit):
|
|
|
2182
2184
|
self._mutated(preserve_placement_cache=True)
|
|
2183
2185
|
return k
|
|
2184
2186
|
|
|
2185
|
-
def insert_into_range(self, operations:
|
|
2187
|
+
def insert_into_range(self, operations: cirq.OP_TREE, start: int, end: int) -> int:
|
|
2186
2188
|
"""Writes operations inline into an area of the circuit.
|
|
2187
2189
|
|
|
2188
2190
|
Args:
|
|
@@ -2225,9 +2227,9 @@ class Circuit(AbstractCircuit):
|
|
|
2225
2227
|
|
|
2226
2228
|
def _push_frontier(
|
|
2227
2229
|
self,
|
|
2228
|
-
early_frontier: Dict[
|
|
2229
|
-
late_frontier: Dict[
|
|
2230
|
-
update_qubits: Optional[Iterable[
|
|
2230
|
+
early_frontier: Dict[cirq.Qid, int],
|
|
2231
|
+
late_frontier: Dict[cirq.Qid, int],
|
|
2232
|
+
update_qubits: Optional[Iterable[cirq.Qid]] = None,
|
|
2231
2233
|
) -> Tuple[int, int]:
|
|
2232
2234
|
"""Inserts moments to separate two frontiers.
|
|
2233
2235
|
|
|
@@ -2270,7 +2272,7 @@ class Circuit(AbstractCircuit):
|
|
|
2270
2272
|
return (0, 0)
|
|
2271
2273
|
|
|
2272
2274
|
def _insert_operations(
|
|
2273
|
-
self, operations: Sequence[
|
|
2275
|
+
self, operations: Sequence[cirq.Operation], insertion_indices: Sequence[int]
|
|
2274
2276
|
) -> None:
|
|
2275
2277
|
"""Inserts operations at the specified moments. Appends new moments if
|
|
2276
2278
|
necessary.
|
|
@@ -2290,18 +2292,15 @@ class Circuit(AbstractCircuit):
|
|
|
2290
2292
|
raise ValueError('operations and insertion_indices must have the same length.')
|
|
2291
2293
|
self._moments += [Moment() for _ in range(1 + max(insertion_indices) - len(self))]
|
|
2292
2294
|
self._mutated()
|
|
2293
|
-
moment_to_ops: Dict[int, List[
|
|
2295
|
+
moment_to_ops: Dict[int, List[cirq.Operation]] = defaultdict(list)
|
|
2294
2296
|
for op_index, moment_index in enumerate(insertion_indices):
|
|
2295
2297
|
moment_to_ops[moment_index].append(operations[op_index])
|
|
2296
2298
|
for moment_index, new_ops in moment_to_ops.items():
|
|
2297
2299
|
self._moments[moment_index] = self._moments[moment_index].with_operations(*new_ops)
|
|
2298
2300
|
|
|
2299
2301
|
def insert_at_frontier(
|
|
2300
|
-
self,
|
|
2301
|
-
|
|
2302
|
-
start: int,
|
|
2303
|
-
frontier: Optional[Dict['cirq.Qid', int]] = None,
|
|
2304
|
-
) -> Dict['cirq.Qid', int]:
|
|
2302
|
+
self, operations: cirq.OP_TREE, start: int, frontier: Optional[Dict[cirq.Qid, int]] = None
|
|
2303
|
+
) -> Dict[cirq.Qid, int]:
|
|
2305
2304
|
"""Inserts operations inline at frontier.
|
|
2306
2305
|
|
|
2307
2306
|
Args:
|
|
@@ -2335,7 +2334,7 @@ class Circuit(AbstractCircuit):
|
|
|
2335
2334
|
|
|
2336
2335
|
return frontier
|
|
2337
2336
|
|
|
2338
|
-
def batch_remove(self, removals: Iterable[Tuple[int,
|
|
2337
|
+
def batch_remove(self, removals: Iterable[Tuple[int, cirq.Operation]]) -> None:
|
|
2339
2338
|
"""Removes several operations from a circuit.
|
|
2340
2339
|
|
|
2341
2340
|
Args:
|
|
@@ -2359,7 +2358,7 @@ class Circuit(AbstractCircuit):
|
|
|
2359
2358
|
self._mutated()
|
|
2360
2359
|
|
|
2361
2360
|
def batch_replace(
|
|
2362
|
-
self, replacements: Iterable[Tuple[int,
|
|
2361
|
+
self, replacements: Iterable[Tuple[int, cirq.Operation, cirq.Operation]]
|
|
2363
2362
|
) -> None:
|
|
2364
2363
|
"""Replaces several operations in a circuit with new operations.
|
|
2365
2364
|
|
|
@@ -2383,7 +2382,7 @@ class Circuit(AbstractCircuit):
|
|
|
2383
2382
|
self._moments = copy._moments
|
|
2384
2383
|
self._mutated()
|
|
2385
2384
|
|
|
2386
|
-
def batch_insert_into(self, insert_intos: Iterable[Tuple[int,
|
|
2385
|
+
def batch_insert_into(self, insert_intos: Iterable[Tuple[int, cirq.OP_TREE]]) -> None:
|
|
2387
2386
|
"""Inserts operations into empty spaces in existing moments.
|
|
2388
2387
|
|
|
2389
2388
|
If any of the insertions fails (due to colliding with an existing
|
|
@@ -2404,7 +2403,7 @@ class Circuit(AbstractCircuit):
|
|
|
2404
2403
|
self._moments = copy._moments
|
|
2405
2404
|
self._mutated()
|
|
2406
2405
|
|
|
2407
|
-
def batch_insert(self, insertions: Iterable[Tuple[int,
|
|
2406
|
+
def batch_insert(self, insertions: Iterable[Tuple[int, cirq.OP_TREE]]) -> None:
|
|
2408
2407
|
"""Applies a batched insert operation to the circuit.
|
|
2409
2408
|
|
|
2410
2409
|
Transparently handles the fact that earlier insertions may shift
|
|
@@ -2441,8 +2440,8 @@ class Circuit(AbstractCircuit):
|
|
|
2441
2440
|
|
|
2442
2441
|
def append(
|
|
2443
2442
|
self,
|
|
2444
|
-
moment_or_operation_tree:
|
|
2445
|
-
strategy:
|
|
2443
|
+
moment_or_operation_tree: cirq.OP_TREE,
|
|
2444
|
+
strategy: cirq.InsertStrategy = InsertStrategy.EARLIEST,
|
|
2446
2445
|
) -> None:
|
|
2447
2446
|
"""Appends operations onto the end of the circuit.
|
|
2448
2447
|
|
|
@@ -2454,9 +2453,7 @@ class Circuit(AbstractCircuit):
|
|
|
2454
2453
|
"""
|
|
2455
2454
|
self.insert(len(self._moments), moment_or_operation_tree, strategy)
|
|
2456
2455
|
|
|
2457
|
-
def clear_operations_touching(
|
|
2458
|
-
self, qubits: Iterable['cirq.Qid'], moment_indices: Iterable[int]
|
|
2459
|
-
):
|
|
2456
|
+
def clear_operations_touching(self, qubits: Iterable[cirq.Qid], moment_indices: Iterable[int]):
|
|
2460
2457
|
"""Clears operations that are touching given qubits at given moments.
|
|
2461
2458
|
|
|
2462
2459
|
Args:
|
|
@@ -2471,10 +2468,10 @@ class Circuit(AbstractCircuit):
|
|
|
2471
2468
|
self._mutated()
|
|
2472
2469
|
|
|
2473
2470
|
@property
|
|
2474
|
-
def moments(self) -> Sequence[
|
|
2471
|
+
def moments(self) -> Sequence[cirq.Moment]:
|
|
2475
2472
|
return self._moments
|
|
2476
2473
|
|
|
2477
|
-
def with_noise(self, noise:
|
|
2474
|
+
def with_noise(self, noise: cirq.NOISE_MODEL_LIKE) -> cirq.Circuit:
|
|
2478
2475
|
"""Make a noisy version of the circuit.
|
|
2479
2476
|
|
|
2480
2477
|
Args:
|
|
@@ -2496,10 +2493,10 @@ class Circuit(AbstractCircuit):
|
|
|
2496
2493
|
|
|
2497
2494
|
|
|
2498
2495
|
def _pick_inserted_ops_moment_indices(
|
|
2499
|
-
operations: Sequence[
|
|
2496
|
+
operations: Sequence[cirq.Operation],
|
|
2500
2497
|
start: int = 0,
|
|
2501
|
-
frontier: Optional[Dict[
|
|
2502
|
-
) -> Tuple[Sequence[int], Dict[
|
|
2498
|
+
frontier: Optional[Dict[cirq.Qid, int]] = None,
|
|
2499
|
+
) -> Tuple[Sequence[int], Dict[cirq.Qid, int]]:
|
|
2503
2500
|
"""Greedily assigns operations to moments.
|
|
2504
2501
|
|
|
2505
2502
|
Args:
|
|
@@ -2525,7 +2522,7 @@ def _pick_inserted_ops_moment_indices(
|
|
|
2525
2522
|
return moment_indices, frontier
|
|
2526
2523
|
|
|
2527
2524
|
|
|
2528
|
-
def _get_moment_annotations(moment:
|
|
2525
|
+
def _get_moment_annotations(moment: cirq.Moment) -> Iterator[cirq.Operation]:
|
|
2529
2526
|
for op in moment.operations:
|
|
2530
2527
|
if op.qubits:
|
|
2531
2528
|
continue
|
|
@@ -2541,14 +2538,14 @@ def _get_moment_annotations(moment: 'cirq.Moment') -> Iterator['cirq.Operation']
|
|
|
2541
2538
|
|
|
2542
2539
|
def _draw_moment_annotations(
|
|
2543
2540
|
*,
|
|
2544
|
-
moment:
|
|
2541
|
+
moment: cirq.Moment,
|
|
2545
2542
|
col: int,
|
|
2546
2543
|
use_unicode_characters: bool,
|
|
2547
|
-
label_map: Dict[
|
|
2548
|
-
out_diagram:
|
|
2544
|
+
label_map: Dict[cirq.LabelEntity, int],
|
|
2545
|
+
out_diagram: cirq.TextDiagramDrawer,
|
|
2549
2546
|
precision: Optional[int],
|
|
2550
2547
|
get_circuit_diagram_info: Callable[
|
|
2551
|
-
[
|
|
2548
|
+
[cirq.Operation, cirq.CircuitDiagramInfoArgs], cirq.CircuitDiagramInfo
|
|
2552
2549
|
],
|
|
2553
2550
|
include_tags: bool,
|
|
2554
2551
|
first_annotation_row: int,
|
|
@@ -2573,14 +2570,14 @@ def _draw_moment_annotations(
|
|
|
2573
2570
|
|
|
2574
2571
|
def _draw_moment_in_diagram(
|
|
2575
2572
|
*,
|
|
2576
|
-
moment:
|
|
2573
|
+
moment: cirq.Moment,
|
|
2577
2574
|
use_unicode_characters: bool,
|
|
2578
|
-
label_map: Dict[
|
|
2579
|
-
out_diagram:
|
|
2575
|
+
label_map: Dict[cirq.LabelEntity, int],
|
|
2576
|
+
out_diagram: cirq.TextDiagramDrawer,
|
|
2580
2577
|
precision: Optional[int],
|
|
2581
2578
|
moment_groups: List[Tuple[int, int]],
|
|
2582
2579
|
get_circuit_diagram_info: Optional[
|
|
2583
|
-
Callable[[
|
|
2580
|
+
Callable[[cirq.Operation, cirq.CircuitDiagramInfoArgs], cirq.CircuitDiagramInfo]
|
|
2584
2581
|
],
|
|
2585
2582
|
include_tags: bool,
|
|
2586
2583
|
first_annotation_row: int,
|
|
@@ -2665,7 +2662,7 @@ def _draw_moment_in_diagram(
|
|
|
2665
2662
|
moment_groups.append((x0, max_x))
|
|
2666
2663
|
|
|
2667
2664
|
|
|
2668
|
-
def _get_global_phase_and_tags_for_op(op:
|
|
2665
|
+
def _get_global_phase_and_tags_for_op(op: cirq.Operation) -> Tuple[Optional[complex], List[Any]]:
|
|
2669
2666
|
if isinstance(op.gate, ops.GlobalPhaseGate):
|
|
2670
2667
|
return complex(op.gate.coefficient), list(op.tags)
|
|
2671
2668
|
elif isinstance(op.untagged, CircuitOperation):
|
|
@@ -2699,7 +2696,7 @@ def _formatted_phase(coefficient: complex, unicode: bool, precision: Optional[in
|
|
|
2699
2696
|
def _draw_moment_groups_in_diagram(
|
|
2700
2697
|
moment_groups: List[Tuple[int, int]],
|
|
2701
2698
|
use_unicode_characters: bool,
|
|
2702
|
-
out_diagram:
|
|
2699
|
+
out_diagram: cirq.TextDiagramDrawer,
|
|
2703
2700
|
):
|
|
2704
2701
|
out_diagram.insert_empty_rows(0)
|
|
2705
2702
|
h = out_diagram.height()
|
|
@@ -2729,9 +2726,9 @@ def _draw_moment_groups_in_diagram(
|
|
|
2729
2726
|
|
|
2730
2727
|
|
|
2731
2728
|
def _apply_unitary_circuit(
|
|
2732
|
-
circuit:
|
|
2729
|
+
circuit: cirq.AbstractCircuit,
|
|
2733
2730
|
state: np.ndarray,
|
|
2734
|
-
qubits: Tuple[
|
|
2731
|
+
qubits: Tuple[cirq.Qid, ...],
|
|
2735
2732
|
dtype: Type[np.complexfloating],
|
|
2736
2733
|
) -> np.ndarray:
|
|
2737
2734
|
"""Applies a circuit's unitary effect to the given vector or matrix.
|
|
@@ -2775,7 +2772,7 @@ def _apply_unitary_circuit(
|
|
|
2775
2772
|
return result
|
|
2776
2773
|
|
|
2777
2774
|
|
|
2778
|
-
def _decompose_measurement_inversions(op:
|
|
2775
|
+
def _decompose_measurement_inversions(op: cirq.Operation) -> cirq.OP_TREE:
|
|
2779
2776
|
if isinstance(op.gate, ops.MeasurementGate):
|
|
2780
2777
|
return [ops.X(q) for q, b in zip(op.qubits, op.gate.invert_mask) if b]
|
|
2781
2778
|
return NotImplemented
|
|
@@ -2848,7 +2845,7 @@ def _group_into_moment_compatible(inputs: Sequence[_MOMENT_OR_OP]) -> Iterator[L
|
|
|
2848
2845
|
[X(a), Moment(X(b)), X(c)] -> [[X(a)], [Moment(X(b))], [X(c)]]
|
|
2849
2846
|
"""
|
|
2850
2847
|
batch: List[_MOMENT_OR_OP] = []
|
|
2851
|
-
batch_qubits: Set[
|
|
2848
|
+
batch_qubits: Set[cirq.Qid] = set()
|
|
2852
2849
|
for mop in inputs:
|
|
2853
2850
|
is_moment = isinstance(mop, cirq.Moment)
|
|
2854
2851
|
if (is_moment and batch) or not batch_qubits.isdisjoint(mop.qubits):
|
|
@@ -2866,9 +2863,9 @@ def _group_into_moment_compatible(inputs: Sequence[_MOMENT_OR_OP]) -> Iterator[L
|
|
|
2866
2863
|
|
|
2867
2864
|
def get_earliest_accommodating_moment_index(
|
|
2868
2865
|
moment_or_operation: _MOMENT_OR_OP,
|
|
2869
|
-
qubit_indices: Dict[
|
|
2870
|
-
mkey_indices: Dict[
|
|
2871
|
-
ckey_indices: Dict[
|
|
2866
|
+
qubit_indices: Dict[cirq.Qid, int],
|
|
2867
|
+
mkey_indices: Dict[cirq.MeasurementKey, int],
|
|
2868
|
+
ckey_indices: Dict[cirq.MeasurementKey, int],
|
|
2872
2869
|
length: Optional[int] = None,
|
|
2873
2870
|
) -> int:
|
|
2874
2871
|
"""Get the index of the earliest moment that can accommodate the given moment or operation.
|
|
@@ -2954,9 +2951,9 @@ class _PlacementCache:
|
|
|
2954
2951
|
|
|
2955
2952
|
def __init__(self) -> None:
|
|
2956
2953
|
# These are dicts from the qubit/key to the greatest moment index that has it.
|
|
2957
|
-
self._qubit_indices: Dict[
|
|
2958
|
-
self._mkey_indices: Dict[
|
|
2959
|
-
self._ckey_indices: Dict[
|
|
2954
|
+
self._qubit_indices: Dict[cirq.Qid, int] = {}
|
|
2955
|
+
self._mkey_indices: Dict[cirq.MeasurementKey, int] = {}
|
|
2956
|
+
self._ckey_indices: Dict[cirq.MeasurementKey, int] = {}
|
|
2960
2957
|
|
|
2961
2958
|
# For keeping track of length of the circuit thus far.
|
|
2962
2959
|
self._length = 0
|