cirq-core 1.6.0.dev20250501173104__py3-none-any.whl → 1.6.0.dev20250501192724__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/transformers/analytical_decompositions/two_qubit_to_cz.py +18 -18
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +18 -19
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +8 -10
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +26 -28
- cirq/transformers/drop_empty_moments.py +4 -2
- cirq/transformers/drop_negligible_operations.py +6 -4
- cirq/transformers/dynamical_decoupling.py +6 -4
- cirq/transformers/dynamical_decoupling_test.py +8 -6
- cirq/transformers/eject_phased_paulis.py +14 -12
- cirq/transformers/eject_z.py +8 -6
- cirq/transformers/expand_composite.py +5 -3
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +3 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -1
- cirq/transformers/insertion_sort.py +6 -4
- cirq/transformers/measurement_transformers.py +21 -21
- cirq/transformers/merge_k_qubit_gates.py +11 -9
- cirq/transformers/merge_k_qubit_gates_test.py +5 -3
- cirq/transformers/merge_single_qubit_gates.py +15 -13
- cirq/transformers/optimize_for_target_gateset.py +14 -12
- cirq/transformers/optimize_for_target_gateset_test.py +7 -3
- cirq/transformers/qubit_management_transformers.py +10 -8
- cirq/transformers/randomized_measurements.py +9 -7
- cirq/transformers/routing/initial_mapper.py +5 -3
- cirq/transformers/routing/line_initial_mapper.py +15 -13
- cirq/transformers/routing/mapping_manager.py +9 -9
- cirq/transformers/routing/route_circuit_cqc.py +17 -15
- cirq/transformers/routing/visualize_routed_circuit.py +7 -6
- cirq/transformers/stratify.py +13 -11
- cirq/transformers/synchronize_terminal_measurements.py +9 -9
- cirq/transformers/target_gatesets/compilation_target_gateset.py +19 -17
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +11 -7
- cirq/transformers/target_gatesets/cz_gateset.py +4 -2
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +5 -3
- cirq/transformers/transformer_api.py +17 -15
- cirq/transformers/transformer_primitives.py +22 -20
- cirq/transformers/transformer_primitives_test.py +3 -1
- cirq/value/classical_data.py +26 -26
- cirq/value/condition.py +23 -21
- cirq/value/duration.py +11 -8
- cirq/value/linear_dict.py +22 -20
- cirq/value/periodic_value.py +4 -4
- cirq/value/probability.py +3 -1
- cirq/value/product_state.py +14 -12
- cirq/work/collector.py +7 -5
- cirq/work/observable_measurement.py +24 -22
- cirq/work/observable_measurement_data.py +9 -7
- cirq/work/observable_readout_calibration.py +4 -1
- cirq/work/observable_readout_calibration_test.py +4 -1
- cirq/work/observable_settings.py +4 -2
- cirq/work/pauli_sum_collector.py +8 -6
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501192724.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501192724.dist-info}/RECORD +57 -57
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501192724.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501192724.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501192724.dist-info}/top_level.txt +0 -0
cirq/value/classical_data.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import abc
|
|
16
18
|
import enum
|
|
17
19
|
from typing import Dict, List, Mapping, Optional, Sequence, Tuple, TYPE_CHECKING
|
|
@@ -45,21 +47,21 @@ class MeasurementType(enum.IntEnum):
|
|
|
45
47
|
|
|
46
48
|
class ClassicalDataStoreReader(abc.ABC):
|
|
47
49
|
@abc.abstractmethod
|
|
48
|
-
def keys(self) -> Tuple[
|
|
50
|
+
def keys(self) -> Tuple[cirq.MeasurementKey, ...]:
|
|
49
51
|
"""Gets the measurement keys in the order they were stored."""
|
|
50
52
|
|
|
51
53
|
@property
|
|
52
54
|
@abc.abstractmethod
|
|
53
|
-
def records(self) -> Mapping[
|
|
55
|
+
def records(self) -> Mapping[cirq.MeasurementKey, List[Tuple[int, ...]]]:
|
|
54
56
|
"""Gets the a mapping from measurement key to measurement records."""
|
|
55
57
|
|
|
56
58
|
@property
|
|
57
59
|
@abc.abstractmethod
|
|
58
|
-
def channel_records(self) -> Mapping[
|
|
60
|
+
def channel_records(self) -> Mapping[cirq.MeasurementKey, List[int]]:
|
|
59
61
|
"""Gets the a mapping from measurement key to channel measurement records."""
|
|
60
62
|
|
|
61
63
|
@abc.abstractmethod
|
|
62
|
-
def get_int(self, key:
|
|
64
|
+
def get_int(self, key: cirq.MeasurementKey, index=-1) -> int:
|
|
63
65
|
"""Gets the integer corresponding to the measurement.
|
|
64
66
|
|
|
65
67
|
The integer is determined by summing the qubit-dimensional basis value
|
|
@@ -81,7 +83,7 @@ class ClassicalDataStoreReader(abc.ABC):
|
|
|
81
83
|
"""
|
|
82
84
|
|
|
83
85
|
@abc.abstractmethod
|
|
84
|
-
def get_digits(self, key:
|
|
86
|
+
def get_digits(self, key: cirq.MeasurementKey, index=-1) -> Tuple[int, ...]:
|
|
85
87
|
"""Gets the values of the qubits that were measured into this key.
|
|
86
88
|
|
|
87
89
|
For example, if the measurement of qubits [q0, q1] produces [0, 1],
|
|
@@ -107,7 +109,7 @@ class ClassicalDataStoreReader(abc.ABC):
|
|
|
107
109
|
class ClassicalDataStore(ClassicalDataStoreReader, abc.ABC):
|
|
108
110
|
@abc.abstractmethod
|
|
109
111
|
def record_measurement(
|
|
110
|
-
self, key:
|
|
112
|
+
self, key: cirq.MeasurementKey, measurement: Sequence[int], qubits: Sequence[cirq.Qid]
|
|
111
113
|
):
|
|
112
114
|
"""Records a measurement.
|
|
113
115
|
|
|
@@ -122,7 +124,7 @@ class ClassicalDataStore(ClassicalDataStoreReader, abc.ABC):
|
|
|
122
124
|
"""
|
|
123
125
|
|
|
124
126
|
@abc.abstractmethod
|
|
125
|
-
def record_channel_measurement(self, key:
|
|
127
|
+
def record_channel_measurement(self, key: cirq.MeasurementKey, measurement: int):
|
|
126
128
|
"""Records a channel measurement.
|
|
127
129
|
|
|
128
130
|
Args:
|
|
@@ -141,12 +143,10 @@ class ClassicalDataDictionaryStore(ClassicalDataStore):
|
|
|
141
143
|
def __init__(
|
|
142
144
|
self,
|
|
143
145
|
*,
|
|
144
|
-
_records: Optional[Dict[
|
|
145
|
-
_measured_qubits: Optional[
|
|
146
|
-
|
|
147
|
-
] = None,
|
|
148
|
-
_channel_records: Optional[Dict['cirq.MeasurementKey', List[int]]] = None,
|
|
149
|
-
_measurement_types: Optional[Dict['cirq.MeasurementKey', 'cirq.MeasurementType']] = None,
|
|
146
|
+
_records: Optional[Dict[cirq.MeasurementKey, List[Tuple[int, ...]]]] = None,
|
|
147
|
+
_measured_qubits: Optional[Dict[cirq.MeasurementKey, List[Tuple[cirq.Qid, ...]]]] = None,
|
|
148
|
+
_channel_records: Optional[Dict[cirq.MeasurementKey, List[int]]] = None,
|
|
149
|
+
_measurement_types: Optional[Dict[cirq.MeasurementKey, cirq.MeasurementType]] = None,
|
|
150
150
|
):
|
|
151
151
|
"""Initializes a `ClassicalDataDictionaryStore` object."""
|
|
152
152
|
if not _measurement_types:
|
|
@@ -165,40 +165,40 @@ class ClassicalDataDictionaryStore(ClassicalDataStore):
|
|
|
165
165
|
_measured_qubits = {}
|
|
166
166
|
if _channel_records is None:
|
|
167
167
|
_channel_records = {}
|
|
168
|
-
self._records: Dict[
|
|
169
|
-
self._measured_qubits: Dict[
|
|
168
|
+
self._records: Dict[cirq.MeasurementKey, List[Tuple[int, ...]]] = _records
|
|
169
|
+
self._measured_qubits: Dict[cirq.MeasurementKey, List[Tuple[cirq.Qid, ...]]] = (
|
|
170
170
|
_measured_qubits
|
|
171
171
|
)
|
|
172
|
-
self._channel_records: Dict[
|
|
173
|
-
self._measurement_types: Dict[
|
|
172
|
+
self._channel_records: Dict[cirq.MeasurementKey, List[int]] = _channel_records
|
|
173
|
+
self._measurement_types: Dict[cirq.MeasurementKey, cirq.MeasurementType] = (
|
|
174
174
|
_measurement_types
|
|
175
175
|
)
|
|
176
176
|
|
|
177
177
|
@property
|
|
178
|
-
def records(self) -> Mapping[
|
|
178
|
+
def records(self) -> Mapping[cirq.MeasurementKey, List[Tuple[int, ...]]]:
|
|
179
179
|
"""Gets the a mapping from measurement key to measurement records."""
|
|
180
180
|
return self._records
|
|
181
181
|
|
|
182
182
|
@property
|
|
183
|
-
def channel_records(self) -> Mapping[
|
|
183
|
+
def channel_records(self) -> Mapping[cirq.MeasurementKey, List[int]]:
|
|
184
184
|
"""Gets the a mapping from measurement key to channel measurement records."""
|
|
185
185
|
return self._channel_records
|
|
186
186
|
|
|
187
187
|
@property
|
|
188
|
-
def measured_qubits(self) -> Mapping[
|
|
188
|
+
def measured_qubits(self) -> Mapping[cirq.MeasurementKey, List[Tuple[cirq.Qid, ...]]]:
|
|
189
189
|
"""Gets the a mapping from measurement key to the qubits measured."""
|
|
190
190
|
return self._measured_qubits
|
|
191
191
|
|
|
192
192
|
@property
|
|
193
|
-
def measurement_types(self) -> Mapping[
|
|
193
|
+
def measurement_types(self) -> Mapping[cirq.MeasurementKey, cirq.MeasurementType]:
|
|
194
194
|
"""Gets the a mapping from measurement key to the measurement type."""
|
|
195
195
|
return self._measurement_types
|
|
196
196
|
|
|
197
|
-
def keys(self) -> Tuple[
|
|
197
|
+
def keys(self) -> Tuple[cirq.MeasurementKey, ...]:
|
|
198
198
|
return tuple(self._measurement_types.keys())
|
|
199
199
|
|
|
200
200
|
def record_measurement(
|
|
201
|
-
self, key:
|
|
201
|
+
self, key: cirq.MeasurementKey, measurement: Sequence[int], qubits: Sequence[cirq.Qid]
|
|
202
202
|
):
|
|
203
203
|
if len(measurement) != len(qubits):
|
|
204
204
|
raise ValueError(f'{len(measurement)} measurements but {len(qubits)} qubits.')
|
|
@@ -217,7 +217,7 @@ class ClassicalDataDictionaryStore(ClassicalDataStore):
|
|
|
217
217
|
measured_qubits.append(tuple(qubits))
|
|
218
218
|
self._records[key].append(tuple(measurement))
|
|
219
219
|
|
|
220
|
-
def record_channel_measurement(self, key:
|
|
220
|
+
def record_channel_measurement(self, key: cirq.MeasurementKey, measurement: int):
|
|
221
221
|
if key not in self._measurement_types:
|
|
222
222
|
self._measurement_types[key] = MeasurementType.CHANNEL
|
|
223
223
|
self._channel_records[key] = []
|
|
@@ -225,14 +225,14 @@ class ClassicalDataDictionaryStore(ClassicalDataStore):
|
|
|
225
225
|
raise ValueError(f"Measurement already logged to key {key}")
|
|
226
226
|
self._channel_records[key].append(measurement)
|
|
227
227
|
|
|
228
|
-
def get_digits(self, key:
|
|
228
|
+
def get_digits(self, key: cirq.MeasurementKey, index=-1) -> Tuple[int, ...]:
|
|
229
229
|
return (
|
|
230
230
|
self._records[key][index]
|
|
231
231
|
if self._measurement_types[key] == MeasurementType.MEASUREMENT
|
|
232
232
|
else (self._channel_records[key][index],)
|
|
233
233
|
)
|
|
234
234
|
|
|
235
|
-
def get_int(self, key:
|
|
235
|
+
def get_int(self, key: cirq.MeasurementKey, index=-1) -> int:
|
|
236
236
|
if key not in self._measurement_types:
|
|
237
237
|
raise KeyError(f'The measurement key {key} is not in {self._measurement_types}')
|
|
238
238
|
measurement_type = self._measurement_types[key]
|
cirq/value/condition.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import abc
|
|
16
18
|
import dataclasses
|
|
17
19
|
from typing import Any, Dict, FrozenSet, Mapping, Optional, Tuple, TYPE_CHECKING
|
|
@@ -32,15 +34,15 @@ class Condition(abc.ABC):
|
|
|
32
34
|
|
|
33
35
|
@property
|
|
34
36
|
@abc.abstractmethod
|
|
35
|
-
def keys(self) -> Tuple[
|
|
37
|
+
def keys(self) -> Tuple[cirq.MeasurementKey, ...]:
|
|
36
38
|
"""Gets the control keys."""
|
|
37
39
|
|
|
38
40
|
@abc.abstractmethod
|
|
39
|
-
def replace_key(self, current:
|
|
41
|
+
def replace_key(self, current: cirq.MeasurementKey, replacement: cirq.MeasurementKey):
|
|
40
42
|
"""Replaces the control keys."""
|
|
41
43
|
|
|
42
44
|
@abc.abstractmethod
|
|
43
|
-
def resolve(self, classical_data:
|
|
45
|
+
def resolve(self, classical_data: cirq.ClassicalDataStoreReader) -> bool:
|
|
44
46
|
"""Resolves the condition based on the measurements."""
|
|
45
47
|
|
|
46
48
|
@property
|
|
@@ -48,24 +50,24 @@ class Condition(abc.ABC):
|
|
|
48
50
|
def qasm(self):
|
|
49
51
|
"""Returns the qasm of this condition."""
|
|
50
52
|
|
|
51
|
-
def _qasm_(self, args:
|
|
53
|
+
def _qasm_(self, args: cirq.QasmArgs, **kwargs) -> Optional[str]:
|
|
52
54
|
return self.qasm
|
|
53
55
|
|
|
54
|
-
def _with_measurement_key_mapping_(self, key_map: Mapping[str, str]) ->
|
|
56
|
+
def _with_measurement_key_mapping_(self, key_map: Mapping[str, str]) -> cirq.Condition:
|
|
55
57
|
condition = self
|
|
56
58
|
for k in self.keys:
|
|
57
59
|
condition = condition.replace_key(k, mkp.with_measurement_key_mapping(k, key_map))
|
|
58
60
|
return condition
|
|
59
61
|
|
|
60
|
-
def _with_key_path_prefix_(self, path: Tuple[str, ...]) ->
|
|
62
|
+
def _with_key_path_prefix_(self, path: Tuple[str, ...]) -> cirq.Condition:
|
|
61
63
|
condition = self
|
|
62
64
|
for k in self.keys:
|
|
63
65
|
condition = condition.replace_key(k, mkp.with_key_path_prefix(k, path))
|
|
64
66
|
return condition
|
|
65
67
|
|
|
66
68
|
def _with_rescoped_keys_(
|
|
67
|
-
self, path: Tuple[str, ...], bindable_keys: FrozenSet[
|
|
68
|
-
) ->
|
|
69
|
+
self, path: Tuple[str, ...], bindable_keys: FrozenSet[cirq.MeasurementKey]
|
|
70
|
+
) -> cirq.Condition:
|
|
69
71
|
condition = self
|
|
70
72
|
for key in self.keys:
|
|
71
73
|
for i in range(len(path) + 1):
|
|
@@ -85,14 +87,14 @@ class KeyCondition(Condition):
|
|
|
85
87
|
time of resolution.
|
|
86
88
|
"""
|
|
87
89
|
|
|
88
|
-
key:
|
|
90
|
+
key: cirq.MeasurementKey
|
|
89
91
|
index: int = -1
|
|
90
92
|
|
|
91
93
|
@property
|
|
92
94
|
def keys(self):
|
|
93
95
|
return (self.key,)
|
|
94
96
|
|
|
95
|
-
def replace_key(self, current:
|
|
97
|
+
def replace_key(self, current: cirq.MeasurementKey, replacement: cirq.MeasurementKey):
|
|
96
98
|
return KeyCondition(replacement) if self.key == current else self
|
|
97
99
|
|
|
98
100
|
def __str__(self):
|
|
@@ -103,7 +105,7 @@ class KeyCondition(Condition):
|
|
|
103
105
|
return f'cirq.KeyCondition({self.key!r}, {self.index})'
|
|
104
106
|
return f'cirq.KeyCondition({self.key!r})'
|
|
105
107
|
|
|
106
|
-
def resolve(self, classical_data:
|
|
108
|
+
def resolve(self, classical_data: cirq.ClassicalDataStoreReader) -> bool:
|
|
107
109
|
if self.key not in classical_data.keys():
|
|
108
110
|
raise ValueError(f'Measurement key {self.key} missing when testing classical control')
|
|
109
111
|
return classical_data.get_int(self.key, self.index) != 0
|
|
@@ -119,7 +121,7 @@ class KeyCondition(Condition):
|
|
|
119
121
|
def qasm(self):
|
|
120
122
|
raise ValueError('QASM is defined only for SympyConditions of type key == constant.')
|
|
121
123
|
|
|
122
|
-
def _qasm_(self, args:
|
|
124
|
+
def _qasm_(self, args: cirq.QasmArgs, **kwargs) -> Optional[str]:
|
|
123
125
|
args.validate_version('2.0', '3.0')
|
|
124
126
|
key_str = str(self.key)
|
|
125
127
|
if key_str not in args.meas_key_id_map:
|
|
@@ -162,7 +164,7 @@ class BitMaskKeyCondition(Condition):
|
|
|
162
164
|
- bitmask: Optional bitmask to apply before doing the comparison.
|
|
163
165
|
"""
|
|
164
166
|
|
|
165
|
-
key:
|
|
167
|
+
key: cirq.MeasurementKey = attrs.field(
|
|
166
168
|
converter=lambda x: (
|
|
167
169
|
x
|
|
168
170
|
if isinstance(x, measurement_key.MeasurementKey)
|
|
@@ -180,8 +182,8 @@ class BitMaskKeyCondition(Condition):
|
|
|
180
182
|
|
|
181
183
|
@staticmethod
|
|
182
184
|
def create_equal_mask(
|
|
183
|
-
key:
|
|
184
|
-
) ->
|
|
185
|
+
key: cirq.MeasurementKey, bitmask: int, *, index: int = -1
|
|
186
|
+
) -> BitMaskKeyCondition:
|
|
185
187
|
"""Creates a condition that evaluates (meas & bitmask) == bitmask."""
|
|
186
188
|
return BitMaskKeyCondition(
|
|
187
189
|
key, index, target_value=bitmask, equal_target=True, bitmask=bitmask
|
|
@@ -189,14 +191,14 @@ class BitMaskKeyCondition(Condition):
|
|
|
189
191
|
|
|
190
192
|
@staticmethod
|
|
191
193
|
def create_not_equal_mask(
|
|
192
|
-
key:
|
|
193
|
-
) ->
|
|
194
|
+
key: cirq.MeasurementKey, bitmask: int, *, index: int = -1
|
|
195
|
+
) -> BitMaskKeyCondition:
|
|
194
196
|
"""Creates a condition that evaluates (meas & bitmask) != bitmask."""
|
|
195
197
|
return BitMaskKeyCondition(
|
|
196
198
|
key, index, target_value=bitmask, equal_target=False, bitmask=bitmask
|
|
197
199
|
)
|
|
198
200
|
|
|
199
|
-
def replace_key(self, current:
|
|
201
|
+
def replace_key(self, current: cirq.MeasurementKey, replacement: cirq.MeasurementKey):
|
|
200
202
|
return BitMaskKeyCondition(replacement) if self.key == current else self
|
|
201
203
|
|
|
202
204
|
def __str__(self):
|
|
@@ -218,7 +220,7 @@ class BitMaskKeyCondition(Condition):
|
|
|
218
220
|
parameters = ', '.join(f'{f.name}={repr(values[f.name])}' for f in attrs.fields(type(self)))
|
|
219
221
|
return f'cirq.BitMaskKeyCondition({parameters})'
|
|
220
222
|
|
|
221
|
-
def resolve(self, classical_data:
|
|
223
|
+
def resolve(self, classical_data: cirq.ClassicalDataStoreReader) -> bool:
|
|
222
224
|
if self.key not in classical_data.keys():
|
|
223
225
|
raise ValueError(f'Measurement key {self.key} missing when testing classical control')
|
|
224
226
|
value = classical_data.get_int(self.key, self.index)
|
|
@@ -269,7 +271,7 @@ class SympyCondition(Condition):
|
|
|
269
271
|
# keep the former here.
|
|
270
272
|
)
|
|
271
273
|
|
|
272
|
-
def replace_key(self, current:
|
|
274
|
+
def replace_key(self, current: cirq.MeasurementKey, replacement: cirq.MeasurementKey):
|
|
273
275
|
return SympyCondition(self.expr.subs({str(current): sympy.Symbol(str(replacement))}))
|
|
274
276
|
|
|
275
277
|
def __str__(self):
|
|
@@ -278,7 +280,7 @@ class SympyCondition(Condition):
|
|
|
278
280
|
def __repr__(self):
|
|
279
281
|
return f'cirq.SympyCondition({proper_repr(self.expr)})'
|
|
280
282
|
|
|
281
|
-
def resolve(self, classical_data:
|
|
283
|
+
def resolve(self, classical_data: cirq.ClassicalDataStoreReader) -> bool:
|
|
282
284
|
missing = [str(k) for k in self.keys if k not in classical_data.keys()]
|
|
283
285
|
if missing:
|
|
284
286
|
raise ValueError(f'Measurement keys {missing} missing when testing classical control')
|
cirq/value/duration.py
CHANGED
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""A typed time delta that supports picosecond accuracy."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import datetime
|
|
17
20
|
from typing import AbstractSet, Any, Dict, List, Optional, Tuple, TYPE_CHECKING, Union
|
|
18
21
|
|
|
@@ -98,7 +101,7 @@ class Duration:
|
|
|
98
101
|
def _parameter_names_(self) -> AbstractSet[str]:
|
|
99
102
|
return protocols.parameter_names(self._time_vals)
|
|
100
103
|
|
|
101
|
-
def _resolve_parameters_(self, resolver:
|
|
104
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> Duration:
|
|
102
105
|
return _duration_from_time_vals(
|
|
103
106
|
protocols.resolve_parameters(self._time_vals, resolver, recursive)
|
|
104
107
|
)
|
|
@@ -121,16 +124,16 @@ class Duration:
|
|
|
121
124
|
"""Returns the number of milliseconds that the duration spans."""
|
|
122
125
|
return self.total_picos() / 1000_000_000
|
|
123
126
|
|
|
124
|
-
def __add__(self, other) ->
|
|
127
|
+
def __add__(self, other) -> Duration:
|
|
125
128
|
other = _attempt_duration_like_to_duration(other)
|
|
126
129
|
if other is None:
|
|
127
130
|
return NotImplemented
|
|
128
131
|
return _duration_from_time_vals(_add_time_vals(self._time_vals, other._time_vals))
|
|
129
132
|
|
|
130
|
-
def __radd__(self, other) ->
|
|
133
|
+
def __radd__(self, other) -> Duration:
|
|
131
134
|
return self.__add__(other)
|
|
132
135
|
|
|
133
|
-
def __sub__(self, other) ->
|
|
136
|
+
def __sub__(self, other) -> Duration:
|
|
134
137
|
other = _attempt_duration_like_to_duration(other)
|
|
135
138
|
if other is None:
|
|
136
139
|
return NotImplemented
|
|
@@ -138,7 +141,7 @@ class Duration:
|
|
|
138
141
|
_add_time_vals(self._time_vals, [-x for x in other._time_vals])
|
|
139
142
|
)
|
|
140
143
|
|
|
141
|
-
def __rsub__(self, other) ->
|
|
144
|
+
def __rsub__(self, other) -> Duration:
|
|
142
145
|
other = _attempt_duration_like_to_duration(other)
|
|
143
146
|
if other is None:
|
|
144
147
|
return NotImplemented
|
|
@@ -146,17 +149,17 @@ class Duration:
|
|
|
146
149
|
_add_time_vals(other._time_vals, [-x for x in self._time_vals])
|
|
147
150
|
)
|
|
148
151
|
|
|
149
|
-
def __mul__(self, other) ->
|
|
152
|
+
def __mul__(self, other) -> Duration:
|
|
150
153
|
if not isinstance(other, (int, float, sympy.Expr)):
|
|
151
154
|
return NotImplemented
|
|
152
155
|
if other == 0:
|
|
153
156
|
return _duration_from_time_vals([0] * 4)
|
|
154
157
|
return _duration_from_time_vals([x * other for x in self._time_vals])
|
|
155
158
|
|
|
156
|
-
def __rmul__(self, other) ->
|
|
159
|
+
def __rmul__(self, other) -> Duration:
|
|
157
160
|
return self.__mul__(other)
|
|
158
161
|
|
|
159
|
-
def __truediv__(self, other) -> Union[
|
|
162
|
+
def __truediv__(self, other) -> Union[Duration, float]:
|
|
160
163
|
if isinstance(other, (int, float, sympy.Expr)):
|
|
161
164
|
new_time_vals = [x / other for x in self._time_vals]
|
|
162
165
|
return _duration_from_time_vals(new_time_vals)
|
cirq/value/linear_dict.py
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
"""Linear combination represented as mapping of things to coefficients."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from typing import (
|
|
18
20
|
AbstractSet,
|
|
19
21
|
Any,
|
|
@@ -63,7 +65,7 @@ class _SympyPrinter(sympy.printing.str.StrPrinter):
|
|
|
63
65
|
return super()._print(expr, **kwargs)
|
|
64
66
|
|
|
65
67
|
|
|
66
|
-
def _format_coefficient(format_spec: str, coefficient:
|
|
68
|
+
def _format_coefficient(format_spec: str, coefficient: cirq.TParamValComplex) -> str:
|
|
67
69
|
if isinstance(coefficient, sympy.Basic):
|
|
68
70
|
printer = _SympyPrinter(format_spec)
|
|
69
71
|
return printer.doprint(coefficient)
|
|
@@ -83,7 +85,7 @@ def _format_coefficient(format_spec: str, coefficient: 'cirq.TParamValComplex')
|
|
|
83
85
|
return f'({real_str}+{imag_str}j)'
|
|
84
86
|
|
|
85
87
|
|
|
86
|
-
def _format_term(format_spec: str, vector: TVector, coefficient:
|
|
88
|
+
def _format_term(format_spec: str, vector: TVector, coefficient: cirq.TParamValComplex) -> str:
|
|
87
89
|
coefficient_str = _format_coefficient(format_spec, coefficient)
|
|
88
90
|
if not coefficient_str:
|
|
89
91
|
return coefficient_str
|
|
@@ -93,7 +95,7 @@ def _format_term(format_spec: str, vector: TVector, coefficient: 'cirq.TParamVal
|
|
|
93
95
|
return '+' + result
|
|
94
96
|
|
|
95
97
|
|
|
96
|
-
def _format_terms(terms: Iterable[Tuple[TVector,
|
|
98
|
+
def _format_terms(terms: Iterable[Tuple[TVector, cirq.TParamValComplex]], format_spec: str):
|
|
97
99
|
formatted_terms = [_format_term(format_spec, vector, coeff) for vector, coeff in terms]
|
|
98
100
|
s = ''.join(formatted_terms)
|
|
99
101
|
if not s:
|
|
@@ -120,7 +122,7 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComple
|
|
|
120
122
|
|
|
121
123
|
def __init__(
|
|
122
124
|
self,
|
|
123
|
-
terms: Optional[Mapping[TVector,
|
|
125
|
+
terms: Optional[Mapping[TVector, cirq.TParamValComplex]] = None,
|
|
124
126
|
validator: Optional[Callable[[TVector], bool]] = None,
|
|
125
127
|
) -> None:
|
|
126
128
|
"""Initializes linear combination from a collection of terms.
|
|
@@ -136,7 +138,7 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComple
|
|
|
136
138
|
"""
|
|
137
139
|
self._has_validator = validator is not None
|
|
138
140
|
self._is_valid = validator or (lambda x: True)
|
|
139
|
-
self._terms: Dict[TVector,
|
|
141
|
+
self._terms: Dict[TVector, cirq.TParamValComplex] = {}
|
|
140
142
|
if terms is not None:
|
|
141
143
|
self.update(terms)
|
|
142
144
|
|
|
@@ -172,31 +174,31 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComple
|
|
|
172
174
|
snapshot = self.copy().clean(atol=0)
|
|
173
175
|
return snapshot._terms.keys()
|
|
174
176
|
|
|
175
|
-
def values(self) -> ValuesView[
|
|
177
|
+
def values(self) -> ValuesView[cirq.TParamValComplex]:
|
|
176
178
|
snapshot = self.copy().clean(atol=0)
|
|
177
179
|
return snapshot._terms.values()
|
|
178
180
|
|
|
179
|
-
def items(self) -> ItemsView[TVector,
|
|
181
|
+
def items(self) -> ItemsView[TVector, cirq.TParamValComplex]:
|
|
180
182
|
snapshot = self.copy().clean(atol=0)
|
|
181
183
|
return snapshot._terms.items()
|
|
182
184
|
|
|
183
185
|
# pylint: disable=function-redefined
|
|
184
186
|
@overload
|
|
185
187
|
def update(
|
|
186
|
-
self, other: Mapping[TVector,
|
|
188
|
+
self, other: Mapping[TVector, cirq.TParamValComplex], **kwargs: cirq.TParamValComplex
|
|
187
189
|
) -> None:
|
|
188
190
|
pass
|
|
189
191
|
|
|
190
192
|
@overload
|
|
191
193
|
def update(
|
|
192
194
|
self,
|
|
193
|
-
other: Iterable[Tuple[TVector,
|
|
194
|
-
**kwargs:
|
|
195
|
+
other: Iterable[Tuple[TVector, cirq.TParamValComplex]],
|
|
196
|
+
**kwargs: cirq.TParamValComplex,
|
|
195
197
|
) -> None:
|
|
196
198
|
pass
|
|
197
199
|
|
|
198
200
|
@overload
|
|
199
|
-
def update(self, *args: Any, **kwargs:
|
|
201
|
+
def update(self, *args: Any, **kwargs: cirq.TParamValComplex) -> None:
|
|
200
202
|
pass
|
|
201
203
|
|
|
202
204
|
def update(self, *args, **kwargs):
|
|
@@ -211,11 +213,11 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComple
|
|
|
211
213
|
self.clean(atol=0)
|
|
212
214
|
|
|
213
215
|
@overload
|
|
214
|
-
def get(self, vector: TVector) ->
|
|
216
|
+
def get(self, vector: TVector) -> cirq.TParamValComplex:
|
|
215
217
|
pass
|
|
216
218
|
|
|
217
219
|
@overload
|
|
218
|
-
def get(self, vector: TVector, default: TDefault) -> Union[
|
|
220
|
+
def get(self, vector: TVector, default: TDefault) -> Union[cirq.TParamValComplex, TDefault]:
|
|
219
221
|
pass
|
|
220
222
|
|
|
221
223
|
def get(self, vector, default=0):
|
|
@@ -228,10 +230,10 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComple
|
|
|
228
230
|
def __contains__(self, vector: Any) -> bool:
|
|
229
231
|
return vector in self._terms and self._terms[vector] != 0
|
|
230
232
|
|
|
231
|
-
def __getitem__(self, vector: TVector) ->
|
|
233
|
+
def __getitem__(self, vector: TVector) -> cirq.TParamValComplex:
|
|
232
234
|
return self._terms.get(vector, 0)
|
|
233
235
|
|
|
234
|
-
def __setitem__(self, vector: TVector, coefficient:
|
|
236
|
+
def __setitem__(self, vector: TVector, coefficient: cirq.TParamValComplex) -> None:
|
|
235
237
|
self._check_vector_valid(vector)
|
|
236
238
|
if coefficient != 0:
|
|
237
239
|
self._terms[vector] = coefficient
|
|
@@ -279,21 +281,21 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComple
|
|
|
279
281
|
factory = type(self)
|
|
280
282
|
return factory({v: -c for v, c in self.items()})
|
|
281
283
|
|
|
282
|
-
def __imul__(self, a:
|
|
284
|
+
def __imul__(self, a: cirq.TParamValComplex) -> Self:
|
|
283
285
|
for vector in self:
|
|
284
286
|
self._terms[vector] *= a
|
|
285
287
|
self.clean(atol=0)
|
|
286
288
|
return self
|
|
287
289
|
|
|
288
|
-
def __mul__(self, a:
|
|
290
|
+
def __mul__(self, a: cirq.TParamValComplex) -> Self:
|
|
289
291
|
result = self.copy()
|
|
290
292
|
result *= a
|
|
291
293
|
return result.copy()
|
|
292
294
|
|
|
293
|
-
def __rmul__(self, a:
|
|
295
|
+
def __rmul__(self, a: cirq.TParamValComplex) -> Self:
|
|
294
296
|
return self.__mul__(a)
|
|
295
297
|
|
|
296
|
-
def __truediv__(self, a:
|
|
298
|
+
def __truediv__(self, a: cirq.TParamValComplex) -> Self:
|
|
297
299
|
return self.__mul__(1 / a)
|
|
298
300
|
|
|
299
301
|
def __bool__(self) -> bool:
|
|
@@ -370,7 +372,7 @@ class LinearDict(Generic[TVector], MutableMapping[TVector, 'cirq.TParamValComple
|
|
|
370
372
|
def _parameter_names_(self) -> AbstractSet[str]:
|
|
371
373
|
return set(name for v in self._terms.values() for name in protocols.parameter_names(v))
|
|
372
374
|
|
|
373
|
-
def _resolve_parameters_(self, resolver:
|
|
375
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> LinearDict:
|
|
374
376
|
result = self.copy()
|
|
375
377
|
result.update(
|
|
376
378
|
{
|
cirq/value/periodic_value.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 AbstractSet, Any, TYPE_CHECKING
|
|
16
18
|
|
|
17
19
|
import sympy
|
|
@@ -35,7 +37,7 @@ class PeriodicValue:
|
|
|
35
37
|
interval.
|
|
36
38
|
"""
|
|
37
39
|
|
|
38
|
-
def __init__(self, value:
|
|
40
|
+
def __init__(self, value: cirq.TParamVal, period: cirq.TParamVal):
|
|
39
41
|
"""Initializes the equivalence class.
|
|
40
42
|
|
|
41
43
|
Args:
|
|
@@ -99,9 +101,7 @@ class PeriodicValue:
|
|
|
99
101
|
|
|
100
102
|
return parameter_names(self.value) | parameter_names(self.period)
|
|
101
103
|
|
|
102
|
-
def _resolve_parameters_(
|
|
103
|
-
self, resolver: 'cirq.ParamResolver', recursive: bool
|
|
104
|
-
) -> 'PeriodicValue':
|
|
104
|
+
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> PeriodicValue:
|
|
105
105
|
# HACK: Avoids circular dependencies.
|
|
106
106
|
from cirq.protocols import resolve_parameters
|
|
107
107
|
|
cirq/value/probability.py
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utilities for handling probabilities."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from typing import TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
import numpy as np
|
|
@@ -44,7 +46,7 @@ def validate_probability(p: float, p_str: str) -> float:
|
|
|
44
46
|
return p
|
|
45
47
|
|
|
46
48
|
|
|
47
|
-
def state_vector_to_probabilities(state_vector:
|
|
49
|
+
def state_vector_to_probabilities(state_vector: cirq.STATE_VECTOR_LIKE) -> np.ndarray:
|
|
48
50
|
"""Function to transform a state vector like object into a numpy array of probabilities."""
|
|
49
51
|
valid_state_vector = to_valid_state_vector(state_vector)
|
|
50
52
|
return np.abs(valid_state_vector) ** 2
|