cirq-core 1.5.0.dev20250403161251__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.dev20250403161251.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/METADATA +1 -1
- {cirq_core-1.5.0.dev20250403161251.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/RECORD +54 -54
- {cirq_core-1.5.0.dev20250403161251.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250403161251.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/WHEEL +0 -0
- {cirq_core-1.5.0.dev20250403161251.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import math
|
|
16
18
|
from typing import Any, cast, Dict, Iterator, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
|
|
17
19
|
|
|
@@ -158,7 +160,7 @@ class BayesianNetworkGate(raw_types.Gate):
|
|
|
158
160
|
raise ValueError('Conditional prob should be between 0 and 1.')
|
|
159
161
|
self._arc_probs = arc_probs
|
|
160
162
|
|
|
161
|
-
def _decompose_(self, qubits: Sequence[
|
|
163
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
162
164
|
parameter_names = [init_prob[0] for init_prob in self._init_probs]
|
|
163
165
|
qubit_map = dict(zip(parameter_names, qubits))
|
|
164
166
|
|
|
@@ -188,7 +190,7 @@ class BayesianNetworkGate(raw_types.Gate):
|
|
|
188
190
|
init_probs: List[List[Union[str, Optional[float]]]],
|
|
189
191
|
arc_probs: List[List[Union[str, List[str], List[float]]]],
|
|
190
192
|
**kwargs,
|
|
191
|
-
) ->
|
|
193
|
+
) -> BayesianNetworkGate:
|
|
192
194
|
converted_init_probs = cast(
|
|
193
195
|
List[Tuple[str, Optional[float]]],
|
|
194
196
|
[(param, init_prob) for param, init_prob in init_probs],
|
|
@@ -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 functools
|
|
16
18
|
from typing import Any, Callable, cast, Dict, Generic, Iterator, TypeVar
|
|
17
19
|
|
|
@@ -48,7 +50,7 @@ class Unique(Generic[T]):
|
|
|
48
50
|
return id(self) < id(other)
|
|
49
51
|
|
|
50
52
|
|
|
51
|
-
def _disjoint_qubits(op1:
|
|
53
|
+
def _disjoint_qubits(op1: cirq.Operation, op2: cirq.Operation) -> bool:
|
|
52
54
|
"""Returns true only if the operations have qubits in common."""
|
|
53
55
|
return not set(op1.qubits) & set(op2.qubits)
|
|
54
56
|
|
|
@@ -70,7 +72,7 @@ class CircuitDag(networkx.DiGraph):
|
|
|
70
72
|
|
|
71
73
|
def __init__(
|
|
72
74
|
self,
|
|
73
|
-
can_reorder: Callable[[
|
|
75
|
+
can_reorder: Callable[[cirq.Operation, cirq.Operation], bool] = _disjoint_qubits,
|
|
74
76
|
incoming_graph_data: Any = None,
|
|
75
77
|
) -> None:
|
|
76
78
|
"""Initializes a CircuitDag.
|
|
@@ -91,27 +93,27 @@ class CircuitDag(networkx.DiGraph):
|
|
|
91
93
|
self.can_reorder = can_reorder
|
|
92
94
|
|
|
93
95
|
@staticmethod
|
|
94
|
-
def make_node(op:
|
|
96
|
+
def make_node(op: cirq.Operation) -> Unique:
|
|
95
97
|
return Unique(op)
|
|
96
98
|
|
|
97
99
|
@staticmethod
|
|
98
100
|
def from_circuit(
|
|
99
101
|
circuit: cirq.Circuit,
|
|
100
|
-
can_reorder: Callable[[
|
|
101
|
-
) ->
|
|
102
|
+
can_reorder: Callable[[cirq.Operation, cirq.Operation], bool] = _disjoint_qubits,
|
|
103
|
+
) -> CircuitDag:
|
|
102
104
|
return CircuitDag.from_ops(circuit.all_operations(), can_reorder=can_reorder)
|
|
103
105
|
|
|
104
106
|
@staticmethod
|
|
105
107
|
def from_ops(
|
|
106
|
-
*operations:
|
|
107
|
-
can_reorder: Callable[[
|
|
108
|
-
) ->
|
|
108
|
+
*operations: cirq.OP_TREE,
|
|
109
|
+
can_reorder: Callable[[cirq.Operation, cirq.Operation], bool] = _disjoint_qubits,
|
|
110
|
+
) -> CircuitDag:
|
|
109
111
|
dag = CircuitDag(can_reorder=can_reorder)
|
|
110
112
|
for op in ops.flatten_op_tree(operations):
|
|
111
113
|
dag.append(cast(ops.Operation, op))
|
|
112
114
|
return dag
|
|
113
115
|
|
|
114
|
-
def append(self, op:
|
|
116
|
+
def append(self, op: cirq.Operation) -> None:
|
|
115
117
|
new_node = self.make_node(op)
|
|
116
118
|
for node in list(self.nodes()):
|
|
117
119
|
if not self.can_reorder(node.val, op):
|
|
@@ -140,21 +142,21 @@ class CircuitDag(networkx.DiGraph):
|
|
|
140
142
|
|
|
141
143
|
__hash__ = None # type: ignore
|
|
142
144
|
|
|
143
|
-
def ordered_nodes(self) -> Iterator[Unique[
|
|
145
|
+
def ordered_nodes(self) -> Iterator[Unique[cirq.Operation]]:
|
|
144
146
|
if not self.nodes():
|
|
145
147
|
return
|
|
146
148
|
g = self.copy()
|
|
147
149
|
|
|
148
|
-
def get_root_node(some_node: Unique[
|
|
150
|
+
def get_root_node(some_node: Unique[cirq.Operation]) -> Unique[cirq.Operation]:
|
|
149
151
|
pred = g.pred
|
|
150
152
|
while pred[some_node]:
|
|
151
153
|
some_node = next(iter(pred[some_node]))
|
|
152
154
|
return some_node
|
|
153
155
|
|
|
154
|
-
def get_first_node() -> Unique[
|
|
156
|
+
def get_first_node() -> Unique[cirq.Operation]:
|
|
155
157
|
return get_root_node(next(iter(g.nodes())))
|
|
156
158
|
|
|
157
|
-
def get_next_node(succ: networkx.classes.coreviews.AtlasView) -> Unique[
|
|
159
|
+
def get_next_node(succ: networkx.classes.coreviews.AtlasView) -> Unique[cirq.Operation]:
|
|
158
160
|
if succ:
|
|
159
161
|
return get_root_node(next(iter(succ)))
|
|
160
162
|
|
|
@@ -171,7 +173,7 @@ class CircuitDag(networkx.DiGraph):
|
|
|
171
173
|
|
|
172
174
|
node = get_next_node(succ)
|
|
173
175
|
|
|
174
|
-
def all_operations(self) -> Iterator[
|
|
176
|
+
def all_operations(self) -> Iterator[cirq.Operation]:
|
|
175
177
|
return (node.val for node in self.ordered_nodes())
|
|
176
178
|
|
|
177
179
|
def all_qubits(self):
|
|
@@ -181,8 +183,8 @@ class CircuitDag(networkx.DiGraph):
|
|
|
181
183
|
return cirq.Circuit(self.all_operations(), strategy=cirq.InsertStrategy.EARLIEST)
|
|
182
184
|
|
|
183
185
|
def findall_nodes_until_blocked(
|
|
184
|
-
self, is_blocker: Callable[[
|
|
185
|
-
) -> Iterator[Unique[
|
|
186
|
+
self, is_blocker: Callable[[cirq.Operation], bool]
|
|
187
|
+
) -> Iterator[Unique[cirq.Operation]]:
|
|
186
188
|
"""Finds all nodes before blocking ones.
|
|
187
189
|
|
|
188
190
|
Args:
|
|
@@ -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, Generic, Sequence, Type, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
import numpy as np
|
|
@@ -47,7 +49,7 @@ class CustomStateSimulator(
|
|
|
47
49
|
self,
|
|
48
50
|
state_type: Type[TSimulationState],
|
|
49
51
|
*,
|
|
50
|
-
noise:
|
|
52
|
+
noise: cirq.NOISE_MODEL_LIKE = None,
|
|
51
53
|
split_untangled_states: bool = False,
|
|
52
54
|
):
|
|
53
55
|
"""Initializes a CustomStateSimulator.
|
|
@@ -63,24 +65,24 @@ class CustomStateSimulator(
|
|
|
63
65
|
|
|
64
66
|
def _create_simulator_trial_result(
|
|
65
67
|
self,
|
|
66
|
-
params:
|
|
68
|
+
params: cirq.ParamResolver,
|
|
67
69
|
measurements: Dict[str, np.ndarray],
|
|
68
|
-
final_simulator_state:
|
|
69
|
-
) ->
|
|
70
|
+
final_simulator_state: cirq.SimulationStateBase[TSimulationState],
|
|
71
|
+
) -> CustomStateTrialResult[TSimulationState]:
|
|
70
72
|
return CustomStateTrialResult(
|
|
71
73
|
params, measurements, final_simulator_state=final_simulator_state
|
|
72
74
|
)
|
|
73
75
|
|
|
74
76
|
def _create_step_result(
|
|
75
|
-
self, sim_state:
|
|
76
|
-
) ->
|
|
77
|
+
self, sim_state: cirq.SimulationStateBase[TSimulationState]
|
|
78
|
+
) -> CustomStateStepResult[TSimulationState]:
|
|
77
79
|
return CustomStateStepResult(sim_state)
|
|
78
80
|
|
|
79
81
|
def _create_partial_simulation_state(
|
|
80
82
|
self,
|
|
81
83
|
initial_state: Any,
|
|
82
|
-
qubits: Sequence[
|
|
83
|
-
classical_data:
|
|
84
|
+
qubits: Sequence[cirq.Qid],
|
|
85
|
+
classical_data: cirq.ClassicalDataStore,
|
|
84
86
|
) -> TSimulationState:
|
|
85
87
|
return self.state_type(
|
|
86
88
|
initial_state=initial_state, qubits=qubits, classical_data=classical_data
|
|
@@ -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 List, Sequence, Tuple
|
|
16
18
|
|
|
17
19
|
import numpy as np
|
|
@@ -25,10 +27,10 @@ class ComputationalBasisState(cirq.qis.QuantumStateRepresentation):
|
|
|
25
27
|
def __init__(self, initial_state: List[int]):
|
|
26
28
|
self.basis = initial_state
|
|
27
29
|
|
|
28
|
-
def copy(self, deep_copy_buffers: bool = True) ->
|
|
30
|
+
def copy(self, deep_copy_buffers: bool = True) -> ComputationalBasisState:
|
|
29
31
|
return ComputationalBasisState(self.basis) # pragma: no cover
|
|
30
32
|
|
|
31
|
-
def measure(self, axes: Sequence[int], seed:
|
|
33
|
+
def measure(self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None):
|
|
32
34
|
return [self.basis[i] for i in axes]
|
|
33
35
|
|
|
34
36
|
|
|
@@ -137,18 +139,18 @@ class ComputationalBasisProductState(cirq.qis.QuantumStateRepresentation):
|
|
|
137
139
|
def __init__(self, initial_state: List[int]):
|
|
138
140
|
self.basis = initial_state
|
|
139
141
|
|
|
140
|
-
def copy(self, deep_copy_buffers: bool = True) ->
|
|
142
|
+
def copy(self, deep_copy_buffers: bool = True) -> ComputationalBasisProductState:
|
|
141
143
|
return ComputationalBasisProductState(self.basis)
|
|
142
144
|
|
|
143
|
-
def measure(self, axes: Sequence[int], seed:
|
|
145
|
+
def measure(self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None):
|
|
144
146
|
return [self.basis[i] for i in axes]
|
|
145
147
|
|
|
146
|
-
def kron(self, other:
|
|
148
|
+
def kron(self, other: ComputationalBasisProductState) -> ComputationalBasisProductState:
|
|
147
149
|
return ComputationalBasisProductState(self.basis + other.basis)
|
|
148
150
|
|
|
149
151
|
def factor(
|
|
150
152
|
self, axes: Sequence[int], *, validate=True, atol=1e-07
|
|
151
|
-
) -> Tuple[
|
|
153
|
+
) -> Tuple[ComputationalBasisProductState, ComputationalBasisProductState]:
|
|
152
154
|
extracted = ComputationalBasisProductState(
|
|
153
155
|
[self.basis[i] for i in axes]
|
|
154
156
|
) # pragma: no cover
|
|
@@ -157,7 +159,7 @@ class ComputationalBasisProductState(cirq.qis.QuantumStateRepresentation):
|
|
|
157
159
|
) # pragma: no cover
|
|
158
160
|
return extracted, remainder # pragma: no cover
|
|
159
161
|
|
|
160
|
-
def reindex(self, axes: Sequence[int]) ->
|
|
162
|
+
def reindex(self, axes: Sequence[int]) -> ComputationalBasisProductState:
|
|
161
163
|
return ComputationalBasisProductState([self.basis[i] for i in axes])
|
|
162
164
|
|
|
163
165
|
@property
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import abc
|
|
16
18
|
import itertools
|
|
17
19
|
from typing import cast, Iterable, Optional, Tuple, TYPE_CHECKING
|
|
@@ -150,7 +152,7 @@ class UndirectedGraphDevice(devices.Device):
|
|
|
150
152
|
self.crosstalk_graph = crosstalk_graph
|
|
151
153
|
|
|
152
154
|
@property
|
|
153
|
-
def qubits(self) -> Tuple[
|
|
155
|
+
def qubits(self) -> Tuple[cirq.Qid, ...]:
|
|
154
156
|
return cast(Tuple['cirq.Qid', ...], tuple(sorted(self.device_graph.vertices)))
|
|
155
157
|
|
|
156
158
|
@property
|
|
@@ -192,7 +194,7 @@ class UndirectedGraphDevice(devices.Device):
|
|
|
192
194
|
):
|
|
193
195
|
validator(operation, *crosstalk_operations)
|
|
194
196
|
|
|
195
|
-
def validate_moment(self, moment:
|
|
197
|
+
def validate_moment(self, moment: cirq.Moment):
|
|
196
198
|
super().validate_moment(moment)
|
|
197
199
|
ops = moment.operations
|
|
198
200
|
for i, op in enumerate(ops):
|
|
@@ -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 Sequence, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
from cirq import circuits, devices, ops, value
|
|
@@ -40,7 +42,7 @@ class DepolarizingNoiseModel(devices.NoiseModel):
|
|
|
40
42
|
self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob)
|
|
41
43
|
self._prepend = prepend
|
|
42
44
|
|
|
43
|
-
def noisy_moment(self, moment:
|
|
45
|
+
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
|
|
44
46
|
if validate_all_measurements(moment) or self.is_virtual_moment(moment): # pragma: no cover
|
|
45
47
|
return moment
|
|
46
48
|
|
|
@@ -76,7 +78,7 @@ class ReadoutNoiseModel(devices.NoiseModel):
|
|
|
76
78
|
self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob)
|
|
77
79
|
self._prepend = prepend
|
|
78
80
|
|
|
79
|
-
def noisy_moment(self, moment:
|
|
81
|
+
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
|
|
80
82
|
if self.is_virtual_moment(moment):
|
|
81
83
|
return moment
|
|
82
84
|
if validate_all_measurements(moment):
|
|
@@ -113,7 +115,7 @@ class DampedReadoutNoiseModel(devices.NoiseModel):
|
|
|
113
115
|
self.readout_decay_gate = ops.AmplitudeDampingChannel(decay_prob)
|
|
114
116
|
self._prepend = prepend
|
|
115
117
|
|
|
116
|
-
def noisy_moment(self, moment:
|
|
118
|
+
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
|
|
117
119
|
if self.is_virtual_moment(moment):
|
|
118
120
|
return moment
|
|
119
121
|
if validate_all_measurements(moment):
|
|
@@ -146,7 +148,7 @@ class DepolarizingWithReadoutNoiseModel(devices.NoiseModel):
|
|
|
146
148
|
self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob)
|
|
147
149
|
self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob)
|
|
148
150
|
|
|
149
|
-
def noisy_moment(self, moment:
|
|
151
|
+
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
|
|
150
152
|
if validate_all_measurements(moment):
|
|
151
153
|
return [circuits.Moment(self.readout_noise_gate(q) for q in system_qubits), moment]
|
|
152
154
|
return [moment, circuits.Moment(self.qubit_noise_gate(q) for q in system_qubits)]
|
|
@@ -176,7 +178,7 @@ class DepolarizingWithDampedReadoutNoiseModel(devices.NoiseModel):
|
|
|
176
178
|
self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob)
|
|
177
179
|
self.readout_decay_gate = ops.AmplitudeDampingChannel(decay_prob)
|
|
178
180
|
|
|
179
|
-
def noisy_moment(self, moment:
|
|
181
|
+
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
|
|
180
182
|
if validate_all_measurements(moment):
|
|
181
183
|
return [
|
|
182
184
|
circuits.Moment(self.readout_decay_gate(q) for q in system_qubits),
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
from enum import Enum
|
|
16
18
|
from types import NotImplementedType
|
|
17
19
|
from typing import cast, List, Type, TYPE_CHECKING, Union
|
|
@@ -25,7 +27,7 @@ if TYPE_CHECKING:
|
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
def _matrix_to_clifford_op(
|
|
28
|
-
mat: np.ndarray, qubit:
|
|
30
|
+
mat: np.ndarray, qubit: cirq.Qid, *, atol: float
|
|
29
31
|
) -> Union[ops.Operation, NotImplementedType]:
|
|
30
32
|
rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, atol)
|
|
31
33
|
clifford_gate = ops.SingleQubitCliffordGate.I
|
|
@@ -43,7 +45,7 @@ def _matrix_to_clifford_op(
|
|
|
43
45
|
|
|
44
46
|
|
|
45
47
|
def _matrix_to_pauli_string_phasors(
|
|
46
|
-
mat: np.ndarray, qubit:
|
|
48
|
+
mat: np.ndarray, qubit: cirq.Qid, *, keep_clifford: bool, atol: float
|
|
47
49
|
) -> ops.OP_TREE:
|
|
48
50
|
rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, atol)
|
|
49
51
|
out_ops: List[ops.GateOperation] = []
|
|
@@ -95,7 +97,7 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
95
97
|
"""
|
|
96
98
|
self.atol = atol
|
|
97
99
|
self.single_qubit_target = single_qubit_target
|
|
98
|
-
gates: List[Union[
|
|
100
|
+
gates: List[Union[cirq.Gate, Type[cirq.Gate]]] = [ops.CZ, ops.MeasurementGate]
|
|
99
101
|
if single_qubit_target in [
|
|
100
102
|
self.SingleQubitTarget.SINGLE_QUBIT_CLIFFORDS,
|
|
101
103
|
self.SingleQubitTarget.PAULI_STRING_PHASORS_AND_CLIFFORDS,
|
|
@@ -109,8 +111,8 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
109
111
|
super().__init__(*gates)
|
|
110
112
|
|
|
111
113
|
def _decompose_single_qubit_operation(
|
|
112
|
-
self, op:
|
|
113
|
-
) -> Union[NotImplementedType,
|
|
114
|
+
self, op: cirq.Operation, _
|
|
115
|
+
) -> Union[NotImplementedType, cirq.OP_TREE]:
|
|
114
116
|
if not protocols.has_unitary(op):
|
|
115
117
|
return NotImplemented
|
|
116
118
|
mat = protocols.unitary(op)
|
|
@@ -126,8 +128,8 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
126
128
|
)
|
|
127
129
|
|
|
128
130
|
def _decompose_two_qubit_operation(
|
|
129
|
-
self, op:
|
|
130
|
-
) -> Union[NotImplementedType,
|
|
131
|
+
self, op: cirq.Operation, _
|
|
132
|
+
) -> Union[NotImplementedType, cirq.OP_TREE]:
|
|
131
133
|
if not protocols.has_unitary(op):
|
|
132
134
|
return NotImplemented
|
|
133
135
|
return transformers.two_qubit_matrix_to_cz_operations(
|
|
@@ -139,10 +141,10 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
139
141
|
)
|
|
140
142
|
|
|
141
143
|
@property
|
|
142
|
-
def postprocess_transformers(self) -> List[
|
|
144
|
+
def postprocess_transformers(self) -> List[cirq.TRANSFORMER]:
|
|
143
145
|
"""List of transformers which should be run after decomposing individual operations."""
|
|
144
146
|
|
|
145
|
-
def rewriter(o:
|
|
147
|
+
def rewriter(o: cirq.CircuitOperation):
|
|
146
148
|
result = self._decompose_single_qubit_operation(o, -1)
|
|
147
149
|
return o.circuit.all_operations() if result is NotImplemented else result
|
|
148
150
|
|
|
@@ -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 TYPE_CHECKING
|
|
15
18
|
|
|
16
19
|
from cirq import circuits, ops
|
|
@@ -23,7 +26,7 @@ if TYPE_CHECKING:
|
|
|
23
26
|
import cirq
|
|
24
27
|
|
|
25
28
|
|
|
26
|
-
def qcircuit_qubit_namer(qubit:
|
|
29
|
+
def qcircuit_qubit_namer(qubit: cirq.Qid) -> str:
|
|
27
30
|
"""Returns the latex code for a QCircuit label of given qubit.
|
|
28
31
|
|
|
29
32
|
Args:
|
|
@@ -64,7 +67,7 @@ def _render(diagram: circuits.TextDiagramDrawer) -> str:
|
|
|
64
67
|
|
|
65
68
|
|
|
66
69
|
def circuit_to_latex_using_qcircuit(
|
|
67
|
-
circuit:
|
|
70
|
+
circuit: cirq.Circuit, qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT
|
|
68
71
|
) -> str:
|
|
69
72
|
"""Returns a QCircuit-based latex diagram of the given circuit.
|
|
70
73
|
|
|
@@ -15,7 +15,7 @@ import cirq.contrib.routing as ccr
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def generate_model_circuit(
|
|
18
|
-
num_qubits: int, depth: int, *, random_state:
|
|
18
|
+
num_qubits: int, depth: int, *, random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None
|
|
19
19
|
) -> cirq.Circuit:
|
|
20
20
|
"""Generates a model circuit with the given number of qubits and depth.
|
|
21
21
|
|
|
@@ -277,7 +277,7 @@ def compile_circuit(
|
|
|
277
277
|
# Replace the PermutationGates with regular gates, so we don't proliferate
|
|
278
278
|
# the routing implementation details to the compiler and the device itself.
|
|
279
279
|
|
|
280
|
-
def replace_swap_permutation_gate(op:
|
|
280
|
+
def replace_swap_permutation_gate(op: cirq.Operation, _):
|
|
281
281
|
if isinstance(op.gate, cirq.contrib.acquaintance.SwapPermutationGate):
|
|
282
282
|
return [op.gate.swap_gate.on(*op.qubits)]
|
|
283
283
|
return op
|
|
@@ -327,7 +327,7 @@ def prepare_circuits(
|
|
|
327
327
|
num_qubits: int,
|
|
328
328
|
depth: int,
|
|
329
329
|
num_circuits: int,
|
|
330
|
-
random_state:
|
|
330
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
331
331
|
) -> List[Tuple[cirq.Circuit, List[int]]]:
|
|
332
332
|
"""Generates circuits and computes their heavy set.
|
|
333
333
|
|
|
@@ -423,7 +423,7 @@ def calculate_quantum_volume(
|
|
|
423
423
|
num_circuits: int,
|
|
424
424
|
device_graph: nx.Graph,
|
|
425
425
|
samplers: List[cirq.Sampler],
|
|
426
|
-
random_state:
|
|
426
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
427
427
|
compiler: Optional[Callable[[cirq.Circuit], cirq.Circuit]] = None,
|
|
428
428
|
repetitions=10_000,
|
|
429
429
|
routing_attempts=30,
|
|
@@ -17,6 +17,8 @@ This is based on this paper:
|
|
|
17
17
|
https://arxiv.org/abs/2002.07730
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
20
22
|
import dataclasses
|
|
21
23
|
import math
|
|
22
24
|
from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
|
|
@@ -58,10 +60,10 @@ class MPSSimulator(
|
|
|
58
60
|
|
|
59
61
|
def __init__(
|
|
60
62
|
self,
|
|
61
|
-
noise:
|
|
62
|
-
seed:
|
|
63
|
+
noise: cirq.NOISE_MODEL_LIKE = None,
|
|
64
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
63
65
|
simulation_options: MPSOptions = MPSOptions(),
|
|
64
|
-
grouping: Optional[Dict[
|
|
66
|
+
grouping: Optional[Dict[cirq.Qid, int]] = None,
|
|
65
67
|
):
|
|
66
68
|
"""Creates instance of `MPSSimulator`.
|
|
67
69
|
|
|
@@ -84,10 +86,10 @@ class MPSSimulator(
|
|
|
84
86
|
|
|
85
87
|
def _create_partial_simulation_state(
|
|
86
88
|
self,
|
|
87
|
-
initial_state: Union[int,
|
|
88
|
-
qubits: Sequence[
|
|
89
|
-
classical_data:
|
|
90
|
-
) ->
|
|
89
|
+
initial_state: Union[int, MPSState],
|
|
90
|
+
qubits: Sequence[cirq.Qid],
|
|
91
|
+
classical_data: cirq.ClassicalDataStore,
|
|
92
|
+
) -> MPSState:
|
|
91
93
|
"""Creates MPSState args for simulating the Circuit.
|
|
92
94
|
|
|
93
95
|
Args:
|
|
@@ -114,15 +116,15 @@ class MPSSimulator(
|
|
|
114
116
|
classical_data=classical_data,
|
|
115
117
|
)
|
|
116
118
|
|
|
117
|
-
def _create_step_result(self, sim_state:
|
|
119
|
+
def _create_step_result(self, sim_state: cirq.SimulationStateBase[MPSState]):
|
|
118
120
|
return MPSSimulatorStepResult(sim_state)
|
|
119
121
|
|
|
120
122
|
def _create_simulator_trial_result(
|
|
121
123
|
self,
|
|
122
|
-
params:
|
|
124
|
+
params: cirq.ParamResolver,
|
|
123
125
|
measurements: Dict[str, np.ndarray],
|
|
124
|
-
final_simulator_state:
|
|
125
|
-
) ->
|
|
126
|
+
final_simulator_state: cirq.SimulationStateBase[MPSState],
|
|
127
|
+
) -> MPSTrialResult:
|
|
126
128
|
"""Creates a single trial results with the measurements.
|
|
127
129
|
|
|
128
130
|
Args:
|
|
@@ -144,16 +146,16 @@ class MPSTrialResult(simulator_base.SimulationTrialResultBase['MPSState']):
|
|
|
144
146
|
|
|
145
147
|
def __init__(
|
|
146
148
|
self,
|
|
147
|
-
params:
|
|
149
|
+
params: cirq.ParamResolver,
|
|
148
150
|
measurements: Dict[str, np.ndarray],
|
|
149
|
-
final_simulator_state:
|
|
151
|
+
final_simulator_state: cirq.SimulationStateBase[MPSState],
|
|
150
152
|
) -> None:
|
|
151
153
|
super().__init__(
|
|
152
154
|
params=params, measurements=measurements, final_simulator_state=final_simulator_state
|
|
153
155
|
)
|
|
154
156
|
|
|
155
157
|
@property
|
|
156
|
-
def final_state(self) ->
|
|
158
|
+
def final_state(self) -> MPSState:
|
|
157
159
|
return self._get_merged_sim_state()
|
|
158
160
|
|
|
159
161
|
def __str__(self) -> str:
|
|
@@ -173,7 +175,7 @@ class MPSTrialResult(simulator_base.SimulationTrialResultBase['MPSState']):
|
|
|
173
175
|
class MPSSimulatorStepResult(simulator_base.StepResultBase['MPSState']):
|
|
174
176
|
"""A `StepResult` that can perform measurements."""
|
|
175
177
|
|
|
176
|
-
def __init__(self, sim_state:
|
|
178
|
+
def __init__(self, sim_state: cirq.SimulationStateBase[MPSState]):
|
|
177
179
|
"""Results of a step of the simulator.
|
|
178
180
|
Attributes:
|
|
179
181
|
sim_state: The qubit:SimulationState lookup for this step.
|
|
@@ -309,7 +311,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
|
|
|
309
311
|
def _value_equality_values_(self) -> Any:
|
|
310
312
|
return self._qid_shape, self._M, self._simulation_options, self._grouping
|
|
311
313
|
|
|
312
|
-
def copy(self, deep_copy_buffers: bool = True) ->
|
|
314
|
+
def copy(self, deep_copy_buffers: bool = True) -> _MPSHandler:
|
|
313
315
|
"""Copies the object.
|
|
314
316
|
|
|
315
317
|
Args:
|
|
@@ -520,7 +522,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
|
|
|
520
522
|
return results
|
|
521
523
|
|
|
522
524
|
def measure(
|
|
523
|
-
self, axes: Sequence[int], seed:
|
|
525
|
+
self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None
|
|
524
526
|
) -> List[int]:
|
|
525
527
|
"""Measures the MPS.
|
|
526
528
|
|
|
@@ -533,10 +535,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
|
|
|
533
535
|
return self._measure(axes, value.parse_random_state(seed))
|
|
534
536
|
|
|
535
537
|
def sample(
|
|
536
|
-
self,
|
|
537
|
-
axes: Sequence[int],
|
|
538
|
-
repetitions: int = 1,
|
|
539
|
-
seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
|
|
538
|
+
self, axes: Sequence[int], repetitions: int = 1, seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None
|
|
540
539
|
) -> np.ndarray:
|
|
541
540
|
"""Samples the MPS.
|
|
542
541
|
|
|
@@ -564,12 +563,12 @@ class MPSState(SimulationState[_MPSHandler]):
|
|
|
564
563
|
def __init__(
|
|
565
564
|
self,
|
|
566
565
|
*,
|
|
567
|
-
qubits: Sequence[
|
|
566
|
+
qubits: Sequence[cirq.Qid],
|
|
568
567
|
prng: np.random.RandomState,
|
|
569
568
|
simulation_options: MPSOptions = MPSOptions(),
|
|
570
|
-
grouping: Optional[Dict[
|
|
569
|
+
grouping: Optional[Dict[cirq.Qid, int]] = None,
|
|
571
570
|
initial_state: int = 0,
|
|
572
|
-
classical_data: Optional[
|
|
571
|
+
classical_data: Optional[cirq.ClassicalDataStore] = None,
|
|
573
572
|
):
|
|
574
573
|
"""Creates and MPSState
|
|
575
574
|
|
|
@@ -623,7 +622,7 @@ class MPSState(SimulationState[_MPSHandler]):
|
|
|
623
622
|
"""
|
|
624
623
|
return self._state.state_vector()
|
|
625
624
|
|
|
626
|
-
def partial_trace(self, keep_qubits: Set[
|
|
625
|
+
def partial_trace(self, keep_qubits: Set[cirq.Qid]) -> np.ndarray:
|
|
627
626
|
"""Traces out all qubits except keep_qubits.
|
|
628
627
|
|
|
629
628
|
Args:
|
|
@@ -642,7 +641,7 @@ class MPSState(SimulationState[_MPSHandler]):
|
|
|
642
641
|
return self._state.to_numpy()
|
|
643
642
|
|
|
644
643
|
def _act_on_fallback_(
|
|
645
|
-
self, action: Any, qubits: Sequence[
|
|
644
|
+
self, action: Any, qubits: Sequence[cirq.Qid], allow_decompose: bool = True
|
|
646
645
|
) -> bool:
|
|
647
646
|
"""Delegates the action to self.apply_op"""
|
|
648
647
|
return self._state.apply_op(action, self.get_axes(qubits), self.prng)
|
cirq/contrib/routing/greedy.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import itertools
|
|
16
18
|
from typing import (
|
|
17
19
|
Callable,
|
|
@@ -109,7 +111,7 @@ class _GreedyRouter:
|
|
|
109
111
|
op1.qubits
|
|
110
112
|
)
|
|
111
113
|
& set(op2.qubits),
|
|
112
|
-
random_state:
|
|
114
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
113
115
|
):
|
|
114
116
|
|
|
115
117
|
self.prng = value.parse_random_state(random_state)
|
|
@@ -148,12 +150,12 @@ class _GreedyRouter:
|
|
|
148
150
|
]
|
|
149
151
|
return self.edge_sets[edge_set_size]
|
|
150
152
|
|
|
151
|
-
def log_to_phys(self, *qubits:
|
|
153
|
+
def log_to_phys(self, *qubits: cirq.Qid) -> Iterable[ops.Qid]:
|
|
152
154
|
"""Returns an iterator over the physical qubits mapped to by the given
|
|
153
155
|
logical qubits."""
|
|
154
156
|
return (self._log_to_phys[q] for q in qubits)
|
|
155
157
|
|
|
156
|
-
def phys_to_log(self, *qubits:
|
|
158
|
+
def phys_to_log(self, *qubits: cirq.Qid) -> Iterable[Optional[ops.Qid]]:
|
|
157
159
|
"""Returns an iterator over the logical qubits that map to the given
|
|
158
160
|
physical qubits."""
|
|
159
161
|
return (self._phys_to_log[q] for q in qubits)
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import itertools
|
|
16
18
|
from typing import cast, Dict, Hashable, TYPE_CHECKING
|
|
17
19
|
|
|
@@ -32,7 +34,7 @@ def get_center(graph: nx.Graph) -> Hashable:
|
|
|
32
34
|
def get_initial_mapping(
|
|
33
35
|
logical_graph: nx.Graph,
|
|
34
36
|
device_graph: nx.Graph,
|
|
35
|
-
random_state:
|
|
37
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
36
38
|
) -> Dict[ops.Qid, ops.Qid]:
|
|
37
39
|
"""Gets an initial mapping of logical to physical qubits for routing.
|
|
38
40
|
|