cirq-core 1.6.0.dev20250501173104__py3-none-any.whl → 1.6.0.dev20250501231232__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/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +211 -107
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +347 -3
- 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.dev20250501231232.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/RECORD +59 -59
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/WHEEL +0 -0
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/top_level.txt +0 -0
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
|
cirq/value/product_state.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
|
from dataclasses import dataclass
|
|
17
19
|
from typing import Dict, Iterator, Optional, Sequence, Tuple, TYPE_CHECKING
|
|
@@ -28,7 +30,7 @@ if TYPE_CHECKING:
|
|
|
28
30
|
class _NamedOneQubitState(metaclass=abc.ABCMeta):
|
|
29
31
|
"""Abstract class representing a one-qubit state of note."""
|
|
30
32
|
|
|
31
|
-
def on(self, qubit:
|
|
33
|
+
def on(self, qubit: cirq.Qid) -> ProductState:
|
|
32
34
|
"""Associates one qubit with this named state.
|
|
33
35
|
|
|
34
36
|
The returned object is a ProductState of length 1.
|
|
@@ -57,7 +59,7 @@ class ProductState:
|
|
|
57
59
|
with `cirq.KET_PLUS(q0)`.
|
|
58
60
|
"""
|
|
59
61
|
|
|
60
|
-
states: Dict[
|
|
62
|
+
states: Dict[cirq.Qid, _NamedOneQubitState]
|
|
61
63
|
|
|
62
64
|
def __init__(self, states=None):
|
|
63
65
|
if states is None:
|
|
@@ -66,10 +68,10 @@ class ProductState:
|
|
|
66
68
|
object.__setattr__(self, 'states', states)
|
|
67
69
|
|
|
68
70
|
@property
|
|
69
|
-
def qubits(self) -> Sequence[
|
|
71
|
+
def qubits(self) -> Sequence[cirq.Qid]:
|
|
70
72
|
return sorted(self.states.keys())
|
|
71
73
|
|
|
72
|
-
def __mul__(self, other:
|
|
74
|
+
def __mul__(self, other: cirq.ProductState) -> cirq.ProductState:
|
|
73
75
|
if not isinstance(other, ProductState):
|
|
74
76
|
raise ValueError("Multiplication is only supported with other TensorProductStates.")
|
|
75
77
|
|
|
@@ -93,11 +95,11 @@ class ProductState:
|
|
|
93
95
|
)
|
|
94
96
|
return f'cirq.ProductState({{{states_dict_repr}}})'
|
|
95
97
|
|
|
96
|
-
def __getitem__(self, qubit:
|
|
98
|
+
def __getitem__(self, qubit: cirq.Qid) -> _NamedOneQubitState:
|
|
97
99
|
"""Return the _NamedOneQubitState at the given qubit."""
|
|
98
100
|
return self.states[qubit]
|
|
99
101
|
|
|
100
|
-
def __iter__(self) -> Iterator[Tuple[
|
|
102
|
+
def __iter__(self) -> Iterator[Tuple[cirq.Qid, _NamedOneQubitState]]:
|
|
101
103
|
yield from self.states.items()
|
|
102
104
|
|
|
103
105
|
def __len__(self) -> int:
|
|
@@ -119,7 +121,7 @@ class ProductState:
|
|
|
119
121
|
def _from_json_dict_(cls, states, **kwargs):
|
|
120
122
|
return cls(states=dict(states))
|
|
121
123
|
|
|
122
|
-
def state_vector(self, qubit_order: Optional[
|
|
124
|
+
def state_vector(self, qubit_order: Optional[cirq.QubitOrder] = None) -> np.ndarray:
|
|
123
125
|
"""The state-vector representation of this state."""
|
|
124
126
|
from cirq import ops
|
|
125
127
|
|
|
@@ -136,7 +138,7 @@ class ProductState:
|
|
|
136
138
|
|
|
137
139
|
return mat
|
|
138
140
|
|
|
139
|
-
def projector(self, qubit_order: Optional[
|
|
141
|
+
def projector(self, qubit_order: Optional[cirq.QubitOrder] = None) -> np.ndarray:
|
|
140
142
|
"""The projector associated with this state expressed as a matrix.
|
|
141
143
|
|
|
142
144
|
This is |s⟩⟨s| where |s⟩ is this state.
|
|
@@ -174,7 +176,7 @@ class _PauliEigenState(_NamedOneQubitState):
|
|
|
174
176
|
return f'cirq.{self._symbol}.basis[{self.eigenvalue:+d}]'
|
|
175
177
|
|
|
176
178
|
@abc.abstractmethod
|
|
177
|
-
def stabilized_by(self) -> Tuple[int,
|
|
179
|
+
def stabilized_by(self) -> Tuple[int, cirq.Pauli]:
|
|
178
180
|
pass
|
|
179
181
|
|
|
180
182
|
def __eq__(self, other) -> bool:
|
|
@@ -201,7 +203,7 @@ class _XEigenState(_PauliEigenState):
|
|
|
201
203
|
return np.array([1, -1]) / np.sqrt(2)
|
|
202
204
|
raise ValueError(f"Bad eigenvalue: {self.eigenvalue}") # pragma: no cover
|
|
203
205
|
|
|
204
|
-
def stabilized_by(self) -> Tuple[int,
|
|
206
|
+
def stabilized_by(self) -> Tuple[int, cirq.Pauli]:
|
|
205
207
|
# Prevent circular import from `value.value_equality`
|
|
206
208
|
from cirq import ops
|
|
207
209
|
|
|
@@ -218,7 +220,7 @@ class _YEigenState(_PauliEigenState):
|
|
|
218
220
|
return np.array([1, -1j]) / np.sqrt(2)
|
|
219
221
|
raise ValueError(f"Bad eigenvalue: {self.eigenvalue}") # pragma: no cover
|
|
220
222
|
|
|
221
|
-
def stabilized_by(self) -> Tuple[int,
|
|
223
|
+
def stabilized_by(self) -> Tuple[int, cirq.Pauli]:
|
|
222
224
|
from cirq import ops
|
|
223
225
|
|
|
224
226
|
return self.eigenvalue, ops.Y
|
|
@@ -234,7 +236,7 @@ class _ZEigenState(_PauliEigenState):
|
|
|
234
236
|
return np.array([0, 1])
|
|
235
237
|
raise ValueError(f"Bad eigenvalue: {self.eigenvalue}") # pragma: no cover
|
|
236
238
|
|
|
237
|
-
def stabilized_by(self) -> Tuple[int,
|
|
239
|
+
def stabilized_by(self) -> Tuple[int, cirq.Pauli]:
|
|
238
240
|
from cirq import ops
|
|
239
241
|
|
|
240
242
|
return self.eigenvalue, ops.Z
|
cirq/work/collector.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
|
from typing import Any, Iterator, List, Optional, Tuple, TYPE_CHECKING, Union
|
|
17
19
|
|
|
@@ -29,7 +31,7 @@ if TYPE_CHECKING:
|
|
|
29
31
|
class CircuitSampleJob:
|
|
30
32
|
"""Describes a sampling task."""
|
|
31
33
|
|
|
32
|
-
def __init__(self, circuit:
|
|
34
|
+
def __init__(self, circuit: cirq.AbstractCircuit, *, repetitions: int, tag: Any = None):
|
|
33
35
|
"""Inits CircuitSampleJob.
|
|
34
36
|
|
|
35
37
|
Args:
|
|
@@ -57,7 +59,7 @@ class CircuitSampleJob:
|
|
|
57
59
|
|
|
58
60
|
|
|
59
61
|
class CircuitSampleJobTree(Protocol):
|
|
60
|
-
def __iter__(self) -> Iterator[Union[CircuitSampleJob,
|
|
62
|
+
def __iter__(self) -> Iterator[Union[CircuitSampleJob, CircuitSampleJobTree]]:
|
|
61
63
|
pass
|
|
62
64
|
|
|
63
65
|
|
|
@@ -106,7 +108,7 @@ class Collector(metaclass=abc.ABCMeta):
|
|
|
106
108
|
|
|
107
109
|
def collect(
|
|
108
110
|
self,
|
|
109
|
-
sampler:
|
|
111
|
+
sampler: cirq.Sampler,
|
|
110
112
|
*,
|
|
111
113
|
concurrency: int = 2,
|
|
112
114
|
max_total_samples: Optional[int] = None,
|
|
@@ -141,7 +143,7 @@ class Collector(metaclass=abc.ABCMeta):
|
|
|
141
143
|
|
|
142
144
|
async def collect_async(
|
|
143
145
|
self,
|
|
144
|
-
sampler:
|
|
146
|
+
sampler: cirq.Sampler,
|
|
145
147
|
*,
|
|
146
148
|
concurrency: int = 2,
|
|
147
149
|
max_total_samples: Optional[int] = None,
|
|
@@ -167,7 +169,7 @@ class Collector(metaclass=abc.ABCMeta):
|
|
|
167
169
|
The collector's result after all desired samples have been
|
|
168
170
|
collected.
|
|
169
171
|
"""
|
|
170
|
-
results: duet.AsyncCollector[Tuple[CircuitSampleJob,
|
|
172
|
+
results: duet.AsyncCollector[Tuple[CircuitSampleJob, cirq.Result]] = duet.AsyncCollector()
|
|
171
173
|
job_error = None
|
|
172
174
|
running_jobs = 0
|
|
173
175
|
queued_jobs: List[CircuitSampleJob] = []
|
|
@@ -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
|
import itertools
|
|
@@ -50,8 +52,8 @@ document(
|
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
def _with_parameterized_layers(
|
|
53
|
-
circuit:
|
|
54
|
-
) ->
|
|
55
|
+
circuit: cirq.AbstractCircuit, qubits: Sequence[cirq.Qid], needs_init_layer: bool
|
|
56
|
+
) -> cirq.Circuit:
|
|
55
57
|
"""Return a copy of the input circuit with parameterized single-qubit rotations.
|
|
56
58
|
|
|
57
59
|
These rotations flank the circuit: the initial two layers of X and Y gates
|
|
@@ -136,7 +138,7 @@ class RepetitionsStoppingCriteria(StoppingCriteria):
|
|
|
136
138
|
return protocols.dataclass_json_dict(self)
|
|
137
139
|
|
|
138
140
|
|
|
139
|
-
_OBS_TO_PARAM_VAL: Dict[Tuple[
|
|
141
|
+
_OBS_TO_PARAM_VAL: Dict[Tuple[cirq.Pauli, bool], Tuple[float, float]] = {
|
|
140
142
|
(ops.X, False): (0, -1 / 2),
|
|
141
143
|
(ops.X, True): (0, +1 / 2),
|
|
142
144
|
(ops.Y, False): (1 / 2, 0),
|
|
@@ -148,7 +150,7 @@ _OBS_TO_PARAM_VAL: Dict[Tuple['cirq.Pauli', bool], Tuple[float, float]] = {
|
|
|
148
150
|
second element in the key is whether to measure in the positive or negative (flipped) basis
|
|
149
151
|
for readout symmetrization."""
|
|
150
152
|
|
|
151
|
-
_STATE_TO_PARAM_VAL: Dict[
|
|
153
|
+
_STATE_TO_PARAM_VAL: Dict[_NamedOneQubitState, Tuple[float, float]] = {
|
|
152
154
|
value.KET_PLUS: (0, +1 / 2),
|
|
153
155
|
value.KET_MINUS: (0, -1 / 2),
|
|
154
156
|
value.KET_IMAG: (-1 / 2, 0),
|
|
@@ -162,7 +164,7 @@ _STATE_TO_PARAM_VAL: Dict['_NamedOneQubitState', Tuple[float, float]] = {
|
|
|
162
164
|
def _get_params_for_setting(
|
|
163
165
|
setting: InitObsSetting,
|
|
164
166
|
flips: Iterable[bool],
|
|
165
|
-
qubits: Sequence[
|
|
167
|
+
qubits: Sequence[cirq.Qid],
|
|
166
168
|
needs_init_layer: bool,
|
|
167
169
|
) -> Dict[str, float]:
|
|
168
170
|
"""Return the parameter dictionary for the given setting.
|
|
@@ -204,9 +206,9 @@ def _get_params_for_setting(
|
|
|
204
206
|
|
|
205
207
|
def _pad_setting(
|
|
206
208
|
max_setting: InitObsSetting,
|
|
207
|
-
qubits: Sequence[
|
|
209
|
+
qubits: Sequence[cirq.Qid],
|
|
208
210
|
pad_init_state_with=value.KET_ZERO,
|
|
209
|
-
pad_obs_with:
|
|
211
|
+
pad_obs_with: cirq.Gate = ops.Z,
|
|
210
212
|
) -> InitObsSetting:
|
|
211
213
|
"""Pad `max_setting`'s `init_state` and `observable` with `pad_xx_with` operations
|
|
212
214
|
(defaults: |0> and Z) so each max_setting has the same qubits. We need this
|
|
@@ -303,7 +305,7 @@ class _FlippyMeasSpec:
|
|
|
303
305
|
|
|
304
306
|
meas_spec: _MeasurementSpec
|
|
305
307
|
flips: np.ndarray
|
|
306
|
-
qubits: Sequence[
|
|
308
|
+
qubits: Sequence[cirq.Qid]
|
|
307
309
|
|
|
308
310
|
def param_tuples(self, *, needs_init_layer=True):
|
|
309
311
|
yield from _get_params_for_setting(
|
|
@@ -318,7 +320,7 @@ class _FlippyMeasSpec:
|
|
|
318
320
|
def _subdivide_meas_specs(
|
|
319
321
|
meas_specs: Iterable[_MeasurementSpec],
|
|
320
322
|
repetitions: int,
|
|
321
|
-
qubits: Sequence[
|
|
323
|
+
qubits: Sequence[cirq.Qid],
|
|
322
324
|
readout_symmetrization: bool,
|
|
323
325
|
) -> Tuple[List[_FlippyMeasSpec], int]:
|
|
324
326
|
"""Split measurement specs into sub-jobs for readout symmetrization
|
|
@@ -468,13 +470,13 @@ def _needs_init_layer(grouped_settings: Dict[InitObsSetting, List[InitObsSetting
|
|
|
468
470
|
|
|
469
471
|
|
|
470
472
|
def measure_grouped_settings(
|
|
471
|
-
circuit:
|
|
473
|
+
circuit: cirq.AbstractCircuit,
|
|
472
474
|
grouped_settings: Dict[InitObsSetting, List[InitObsSetting]],
|
|
473
|
-
sampler:
|
|
475
|
+
sampler: cirq.Sampler,
|
|
474
476
|
stopping_criteria: StoppingCriteria,
|
|
475
477
|
*,
|
|
476
478
|
readout_symmetrization: bool = False,
|
|
477
|
-
circuit_sweep:
|
|
479
|
+
circuit_sweep: cirq.Sweepable = None,
|
|
478
480
|
readout_calibrations: Optional[BitstringAccumulator] = None,
|
|
479
481
|
checkpoint: CheckpointFileOptions = CheckpointFileOptions(),
|
|
480
482
|
) -> List[BitstringAccumulator]:
|
|
@@ -597,8 +599,8 @@ def _parse_grouper(grouper: Union[str, GROUPER_T] = group_settings_greedy) -> GR
|
|
|
597
599
|
|
|
598
600
|
|
|
599
601
|
def _get_all_qubits(
|
|
600
|
-
circuit:
|
|
601
|
-
) -> List[
|
|
602
|
+
circuit: cirq.AbstractCircuit, observables: Iterable[cirq.PauliString]
|
|
603
|
+
) -> List[cirq.Qid]:
|
|
602
604
|
"""Helper function for `measure_observables` to get all qubits from a circuit and a
|
|
603
605
|
collection of observables."""
|
|
604
606
|
qubit_set = set()
|
|
@@ -609,13 +611,13 @@ def _get_all_qubits(
|
|
|
609
611
|
|
|
610
612
|
|
|
611
613
|
def measure_observables(
|
|
612
|
-
circuit:
|
|
613
|
-
observables: Iterable[
|
|
614
|
-
sampler: Union[
|
|
614
|
+
circuit: cirq.AbstractCircuit,
|
|
615
|
+
observables: Iterable[cirq.PauliString],
|
|
616
|
+
sampler: Union[cirq.Simulator, cirq.Sampler],
|
|
615
617
|
stopping_criteria: StoppingCriteria,
|
|
616
618
|
*,
|
|
617
619
|
readout_symmetrization: bool = False,
|
|
618
|
-
circuit_sweep: Optional[
|
|
620
|
+
circuit_sweep: Optional[cirq.Sweepable] = None,
|
|
619
621
|
grouper: Union[str, GROUPER_T] = group_settings_greedy,
|
|
620
622
|
readout_calibrations: Optional[BitstringAccumulator] = None,
|
|
621
623
|
checkpoint: CheckpointFileOptions = CheckpointFileOptions(),
|
|
@@ -671,13 +673,13 @@ def measure_observables(
|
|
|
671
673
|
|
|
672
674
|
|
|
673
675
|
def measure_observables_df(
|
|
674
|
-
circuit:
|
|
675
|
-
observables: Iterable[
|
|
676
|
-
sampler: Union[
|
|
676
|
+
circuit: cirq.AbstractCircuit,
|
|
677
|
+
observables: Iterable[cirq.PauliString],
|
|
678
|
+
sampler: Union[cirq.Simulator, cirq.Sampler],
|
|
677
679
|
stopping_criteria: StoppingCriteria,
|
|
678
680
|
*,
|
|
679
681
|
readout_symmetrization: bool = False,
|
|
680
|
-
circuit_sweep: Optional[
|
|
682
|
+
circuit_sweep: Optional[cirq.Sweepable] = None,
|
|
681
683
|
grouper: Union[str, GROUPER_T] = group_settings_greedy,
|
|
682
684
|
readout_calibrations: Optional[BitstringAccumulator] = None,
|
|
683
685
|
checkpoint: CheckpointFileOptions = CheckpointFileOptions(),
|
|
@@ -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 dataclasses
|
|
16
18
|
import datetime
|
|
17
19
|
from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, TYPE_CHECKING, Union
|
|
@@ -33,7 +35,7 @@ if TYPE_CHECKING:
|
|
|
33
35
|
import cirq
|
|
34
36
|
|
|
35
37
|
|
|
36
|
-
def _check_and_get_real_coef(observable:
|
|
38
|
+
def _check_and_get_real_coef(observable: cirq.PauliString, atol: float):
|
|
37
39
|
"""Assert that a PauliString has a real coefficient and return it."""
|
|
38
40
|
coef = observable.coefficient
|
|
39
41
|
if isinstance(coef, sympy.Expr) or not np.isclose(coef.imag, 0, atol=atol):
|
|
@@ -43,8 +45,8 @@ def _check_and_get_real_coef(observable: 'cirq.PauliString', atol: float):
|
|
|
43
45
|
|
|
44
46
|
def _obs_vals_from_measurements(
|
|
45
47
|
bitstrings: np.ndarray,
|
|
46
|
-
qubit_to_index: Dict[
|
|
47
|
-
observable:
|
|
48
|
+
qubit_to_index: Dict[cirq.Qid, int],
|
|
49
|
+
observable: cirq.PauliString,
|
|
48
50
|
atol: float,
|
|
49
51
|
):
|
|
50
52
|
"""Multiply together bitstrings to get observed values of operators."""
|
|
@@ -61,8 +63,8 @@ def _obs_vals_from_measurements(
|
|
|
61
63
|
|
|
62
64
|
def _stats_from_measurements(
|
|
63
65
|
bitstrings: np.ndarray,
|
|
64
|
-
qubit_to_index: Dict[
|
|
65
|
-
observable:
|
|
66
|
+
qubit_to_index: Dict[cirq.Qid, int],
|
|
67
|
+
observable: cirq.PauliString,
|
|
66
68
|
atol: float,
|
|
67
69
|
) -> Tuple[float, float]:
|
|
68
70
|
"""Return the mean and squared standard error of the mean for the given
|
|
@@ -214,11 +216,11 @@ class BitstringAccumulator:
|
|
|
214
216
|
self,
|
|
215
217
|
meas_spec: _MeasurementSpec,
|
|
216
218
|
simul_settings: List[InitObsSetting],
|
|
217
|
-
qubit_to_index: Dict[
|
|
219
|
+
qubit_to_index: Dict[cirq.Qid, int],
|
|
218
220
|
bitstrings: Optional[np.ndarray] = None,
|
|
219
221
|
chunksizes: Optional[np.ndarray] = None,
|
|
220
222
|
timestamps: Optional[np.ndarray] = None,
|
|
221
|
-
readout_calibration: Optional[
|
|
223
|
+
readout_calibration: Optional[BitstringAccumulator] = None,
|
|
222
224
|
):
|
|
223
225
|
self._meas_spec = meas_spec
|
|
224
226
|
self._simul_settings = simul_settings
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# pylint: disable=wrong-or-nonexistent-copyright-notice
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
2
5
|
import dataclasses
|
|
3
6
|
from typing import Iterable, TYPE_CHECKING, Union
|
|
4
7
|
|
|
@@ -12,7 +15,7 @@ if TYPE_CHECKING:
|
|
|
12
15
|
|
|
13
16
|
def calibrate_readout_error(
|
|
14
17
|
qubits: Iterable[ops.Qid],
|
|
15
|
-
sampler: Union[
|
|
18
|
+
sampler: Union[cirq.Simulator, cirq.Sampler],
|
|
16
19
|
stopping_criteria: StoppingCriteria,
|
|
17
20
|
):
|
|
18
21
|
# We know there won't be any fancy sweeps or observables so we can
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# pylint: disable=wrong-or-nonexistent-copyright-notice
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
2
5
|
from typing import Sequence
|
|
3
6
|
|
|
4
7
|
import numpy as np
|
|
@@ -19,7 +22,7 @@ class DepolarizingWithDampedReadoutNoiseModel(cirq.NoiseModel):
|
|
|
19
22
|
self.readout_noise_gate = cirq.BitFlipChannel(bitflip_prob)
|
|
20
23
|
self.readout_decay_gate = cirq.AmplitudeDampingChannel(decay_prob)
|
|
21
24
|
|
|
22
|
-
def noisy_moment(self, moment:
|
|
25
|
+
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
|
|
23
26
|
if cirq.devices.noise_model.validate_all_measurements(moment):
|
|
24
27
|
return [
|
|
25
28
|
cirq.Moment(self.readout_decay_gate(q) for q in system_qubits),
|
cirq/work/observable_settings.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 dataclasses
|
|
16
18
|
import numbers
|
|
17
19
|
from typing import (
|
|
@@ -123,13 +125,13 @@ def _max_weight_state(states: Iterable[value.ProductState]) -> Optional[value.Pr
|
|
|
123
125
|
return value.ProductState(qubit_state_map)
|
|
124
126
|
|
|
125
127
|
|
|
126
|
-
def zeros_state(qubits: Iterable[
|
|
128
|
+
def zeros_state(qubits: Iterable[cirq.Qid]):
|
|
127
129
|
"""Return the ProductState that is |00..00> on all qubits."""
|
|
128
130
|
return value.ProductState({q: value.KET_ZERO for q in qubits})
|
|
129
131
|
|
|
130
132
|
|
|
131
133
|
def observables_to_settings(
|
|
132
|
-
observables: Iterable[
|
|
134
|
+
observables: Iterable[cirq.PauliString], qubits: Iterable[cirq.Qid]
|
|
133
135
|
) -> Iterable[InitObsSetting]:
|
|
134
136
|
"""Transform an observable to an InitObsSetting initialized in the
|
|
135
137
|
all-zeros state.
|
cirq/work/pauli_sum_collector.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 collections
|
|
16
18
|
from typing import cast, Dict, Optional, TYPE_CHECKING, Union
|
|
17
19
|
|
|
@@ -29,8 +31,8 @@ class PauliSumCollector(collector.Collector):
|
|
|
29
31
|
|
|
30
32
|
def __init__(
|
|
31
33
|
self,
|
|
32
|
-
circuit:
|
|
33
|
-
observable:
|
|
34
|
+
circuit: cirq.AbstractCircuit,
|
|
35
|
+
observable: cirq.PauliSumLike,
|
|
34
36
|
*,
|
|
35
37
|
samples_per_term: int,
|
|
36
38
|
max_samples_per_job: int = 1000000,
|
|
@@ -63,7 +65,7 @@ class PauliSumCollector(collector.Collector):
|
|
|
63
65
|
self._samples_per_term = samples_per_term
|
|
64
66
|
self._total_samples_requested = 0
|
|
65
67
|
|
|
66
|
-
def next_job(self) -> Optional[
|
|
68
|
+
def next_job(self) -> Optional[cirq.CircuitSampleJob]:
|
|
67
69
|
i = self._total_samples_requested // self._samples_per_term
|
|
68
70
|
if i >= len(self._pauli_coef_terms):
|
|
69
71
|
return None
|
|
@@ -77,7 +79,7 @@ class PauliSumCollector(collector.Collector):
|
|
|
77
79
|
tag=pauli,
|
|
78
80
|
)
|
|
79
81
|
|
|
80
|
-
def on_job_result(self, job:
|
|
82
|
+
def on_job_result(self, job: cirq.CircuitSampleJob, result: cirq.Result):
|
|
81
83
|
job_id = cast(ops.PauliString, job.tag)
|
|
82
84
|
parities = result.histogram(key='out', fold_func=lambda bits: np.sum(bits) % 2)
|
|
83
85
|
self._zeros[job_id] += parities[0]
|
|
@@ -99,8 +101,8 @@ class PauliSumCollector(collector.Collector):
|
|
|
99
101
|
|
|
100
102
|
|
|
101
103
|
def _circuit_plus_pauli_string_measurements(
|
|
102
|
-
circuit:
|
|
103
|
-
) ->
|
|
104
|
+
circuit: cirq.AbstractCircuit, pauli_string: cirq.PauliString
|
|
105
|
+
) -> cirq.AbstractCircuit:
|
|
104
106
|
"""A circuit measuring the given observable at the end of the given circuit."""
|
|
105
107
|
assert pauli_string
|
|
106
108
|
return circuit.from_moments(
|
{cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cirq-core
|
|
3
|
-
Version: 1.6.0.
|
|
3
|
+
Version: 1.6.0.dev20250501231232
|
|
4
4
|
Summary: A framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
|
|
5
5
|
Home-page: http://github.com/quantumlib/cirq
|
|
6
6
|
Author: The Cirq Developers
|