cirq-core 1.6.0.dev20250424231143__py3-none-any.whl → 1.6.0.dev20250428201230__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/ops/dense_pauli_string.py +28 -28
- cirq/ops/diagonal_gate.py +12 -14
- cirq/ops/eigen_gate.py +8 -5
- cirq/ops/fourier_transform.py +8 -12
- cirq/ops/fsim_gate.py +38 -37
- cirq/ops/gate_operation.py +25 -27
- cirq/ops/gateset.py +7 -5
- cirq/ops/global_phase_op.py +11 -11
- cirq/ops/greedy_qubit_manager.py +9 -7
- cirq/ops/identity.py +8 -6
- cirq/ops/kraus_channel.py +7 -4
- cirq/ops/linear_combinations.py +36 -34
- cirq/ops/matrix_gates.py +10 -10
- cirq/ops/measure_util.py +6 -4
- cirq/ops/measurement_gate.py +12 -12
- cirq/ops/mixed_unitary_channel.py +7 -4
- cirq/ops/named_qubit.py +8 -5
- cirq/ops/op_tree.py +4 -2
- cirq/ops/parallel_gate.py +11 -13
- cirq/ops/parity_gates.py +15 -17
- cirq/ops/pauli_gates.py +20 -17
- cirq/ops/pauli_interaction_gate.py +10 -14
- cirq/ops/pauli_measurement_gate.py +20 -20
- cirq/ops/pauli_string.py +76 -79
- cirq/ops/pauli_string_phasor.py +30 -30
- cirq/ops/pauli_string_raw_types.py +6 -4
- cirq/ops/pauli_sum_exponential.py +11 -11
- cirq/ops/permutation_gate.py +5 -3
- cirq/ops/phased_iswap_gate.py +8 -8
- cirq/ops/phased_x_gate.py +8 -9
- cirq/ops/phased_x_z_gate.py +15 -13
- cirq/ops/qid_util.py +6 -4
- cirq/ops/qubit_manager.py +9 -7
- cirq/ops/random_gate_channel.py +9 -7
- cirq/ops/raw_types.py +70 -72
- cirq/ops/raw_types_test.py +10 -6
- cirq/ops/state_preparation_channel.py +4 -4
- cirq/ops/swap_gates.py +7 -9
- cirq/ops/three_qubit_gates.py +22 -28
- cirq/ops/two_qubit_diagonal_gate.py +8 -8
- cirq/ops/uniform_superposition_gate.py +3 -1
- cirq/ops/wait_gate.py +12 -9
- cirq/protocols/act_on_protocol.py +6 -4
- cirq/protocols/act_on_protocol_test.py +8 -5
- cirq/protocols/apply_unitary_protocol.py +10 -8
- cirq/protocols/circuit_diagram_info_protocol.py +10 -8
- cirq/protocols/control_key_protocol.py +5 -3
- cirq/protocols/decompose_protocol.py +28 -24
- cirq/protocols/decompose_protocol_test.py +5 -2
- cirq/protocols/inverse_protocol.py +10 -8
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/RECORD +57 -57
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/WHEEL +1 -1
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250424231143.dist-info → cirq_core-1.6.0.dev20250428201230.dist-info}/top_level.txt +0 -0
cirq/ops/pauli_string.py
CHANGED
|
@@ -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
|
import cmath
|
|
15
18
|
import math
|
|
16
19
|
import numbers
|
|
@@ -159,9 +162,9 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
159
162
|
|
|
160
163
|
def __init__(
|
|
161
164
|
self,
|
|
162
|
-
*contents:
|
|
163
|
-
qubit_pauli_map: Optional[Dict[TKey,
|
|
164
|
-
coefficient:
|
|
165
|
+
*contents: cirq.PAULI_STRING_LIKE,
|
|
166
|
+
qubit_pauli_map: Optional[Dict[TKey, cirq.Pauli]] = None,
|
|
167
|
+
coefficient: cirq.TParamValComplex = 1,
|
|
165
168
|
):
|
|
166
169
|
"""Initializes a new `PauliString` operation.
|
|
167
170
|
|
|
@@ -188,8 +191,8 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
188
191
|
if not isinstance(v, pauli_gates.Pauli):
|
|
189
192
|
raise TypeError(f'{v} is not a Pauli')
|
|
190
193
|
|
|
191
|
-
self._qubit_pauli_map: Dict[TKey,
|
|
192
|
-
self._coefficient: Union[
|
|
194
|
+
self._qubit_pauli_map: Dict[TKey, cirq.Pauli] = qubit_pauli_map or {}
|
|
195
|
+
self._coefficient: Union[cirq.TParamValComplex, sympy.Expr] = (
|
|
193
196
|
coefficient if isinstance(coefficient, sympy.Expr) else complex(coefficient)
|
|
194
197
|
)
|
|
195
198
|
if contents:
|
|
@@ -198,7 +201,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
198
201
|
self._coefficient = m._coefficient
|
|
199
202
|
|
|
200
203
|
@property
|
|
201
|
-
def coefficient(self) ->
|
|
204
|
+
def coefficient(self) -> cirq.TParamValComplex:
|
|
202
205
|
"""A scalar coefficient or symbol."""
|
|
203
206
|
return self._coefficient
|
|
204
207
|
|
|
@@ -225,7 +228,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
225
228
|
return gate_operation.GateOperation
|
|
226
229
|
return PauliString
|
|
227
230
|
|
|
228
|
-
def equal_up_to_coefficient(self, other:
|
|
231
|
+
def equal_up_to_coefficient(self, other: cirq.PauliString) -> bool:
|
|
229
232
|
"""Returns true of `self` and `other` are equal pauli strings, ignoring the coefficient."""
|
|
230
233
|
return self._qubit_pauli_map == other._qubit_pauli_map
|
|
231
234
|
|
|
@@ -249,28 +252,28 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
249
252
|
|
|
250
253
|
@overload
|
|
251
254
|
def __mul__(
|
|
252
|
-
self, other:
|
|
253
|
-
) ->
|
|
255
|
+
self, other: cirq.PauliString[TKeyOther]
|
|
256
|
+
) -> cirq.PauliString[Union[TKey, TKeyOther]]:
|
|
254
257
|
pass
|
|
255
258
|
|
|
256
259
|
@overload
|
|
257
260
|
def __mul__(
|
|
258
|
-
self, other: Mapping[TKeyOther,
|
|
259
|
-
) ->
|
|
261
|
+
self, other: Mapping[TKeyOther, cirq.PAULI_GATE_LIKE]
|
|
262
|
+
) -> cirq.PauliString[Union[TKey, TKeyOther]]:
|
|
260
263
|
pass
|
|
261
264
|
|
|
262
265
|
@overload
|
|
263
266
|
def __mul__(
|
|
264
|
-
self, other: Iterable[
|
|
265
|
-
) ->
|
|
267
|
+
self, other: Iterable[cirq.PAULI_STRING_LIKE]
|
|
268
|
+
) -> cirq.PauliString[Union[TKey, cirq.Qid]]:
|
|
266
269
|
pass
|
|
267
270
|
|
|
268
271
|
@overload
|
|
269
|
-
def __mul__(self, other:
|
|
272
|
+
def __mul__(self, other: cirq.Operation) -> cirq.PauliString[Union[TKey, cirq.Qid]]:
|
|
270
273
|
pass
|
|
271
274
|
|
|
272
275
|
@overload
|
|
273
|
-
def __mul__(self, other: complex) ->
|
|
276
|
+
def __mul__(self, other: complex) -> cirq.PauliString[TKey]:
|
|
274
277
|
pass
|
|
275
278
|
|
|
276
279
|
def __mul__(self, other):
|
|
@@ -290,7 +293,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
290
293
|
# pylint: enable=function-redefined
|
|
291
294
|
|
|
292
295
|
@property
|
|
293
|
-
def gate(self) ->
|
|
296
|
+
def gate(self) -> cirq.DensePauliString:
|
|
294
297
|
"""Returns a `cirq.DensePauliString`"""
|
|
295
298
|
order: List[Optional[pauli_gates.Pauli]] = [
|
|
296
299
|
None,
|
|
@@ -304,7 +307,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
304
307
|
coefficient=self.coefficient, pauli_mask=[order.index(self[q]) for q in self.qubits]
|
|
305
308
|
)
|
|
306
309
|
|
|
307
|
-
def __rmul__(self, other) ->
|
|
310
|
+
def __rmul__(self, other) -> PauliString:
|
|
308
311
|
if isinstance(other, numbers.Complex):
|
|
309
312
|
return PauliString(
|
|
310
313
|
qubit_pauli_map=self._qubit_pauli_map, coefficient=self._coefficient * other
|
|
@@ -359,7 +362,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
359
362
|
"""Returns a tuple of qubits on which this pauli string acts."""
|
|
360
363
|
return tuple(self.keys())
|
|
361
364
|
|
|
362
|
-
def _circuit_diagram_info_(self, args:
|
|
365
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> List[str]:
|
|
363
366
|
if not len(self._qubit_pauli_map):
|
|
364
367
|
return NotImplemented
|
|
365
368
|
|
|
@@ -380,7 +383,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
380
383
|
symbols[0] = f'PauliString({prefix}{symbols[0]})'
|
|
381
384
|
return symbols
|
|
382
385
|
|
|
383
|
-
def with_qubits(self, *new_qubits:
|
|
386
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> PauliString:
|
|
384
387
|
"""Returns a new `PauliString` with `self.qubits` mapped to `new_qubits`.
|
|
385
388
|
|
|
386
389
|
Args:
|
|
@@ -402,7 +405,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
402
405
|
coefficient=self._coefficient,
|
|
403
406
|
)
|
|
404
407
|
|
|
405
|
-
def with_coefficient(self, new_coefficient:
|
|
408
|
+
def with_coefficient(self, new_coefficient: cirq.TParamValComplex) -> PauliString:
|
|
406
409
|
"""Returns a new `PauliString` with `self.coefficient` replaced with `new_coefficient`."""
|
|
407
410
|
return PauliString(qubit_pauli_map=dict(self._qubit_pauli_map), coefficient=new_coefficient)
|
|
408
411
|
|
|
@@ -414,11 +417,11 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
414
417
|
"""Returns (cirq.Qid, cirq.Pauli) pairs representing 1-qubit operations of pauli string."""
|
|
415
418
|
return self._qubit_pauli_map.items()
|
|
416
419
|
|
|
417
|
-
def frozen(self) ->
|
|
420
|
+
def frozen(self) -> cirq.PauliString:
|
|
418
421
|
"""Returns a `cirq.PauliString` with the same contents."""
|
|
419
422
|
return self
|
|
420
423
|
|
|
421
|
-
def mutable_copy(self) ->
|
|
424
|
+
def mutable_copy(self) -> cirq.MutablePauliString:
|
|
422
425
|
"""Returns a new `cirq.MutablePauliString` with the same contents."""
|
|
423
426
|
return MutablePauliString(
|
|
424
427
|
coefficient=self.coefficient,
|
|
@@ -510,7 +513,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
510
513
|
return None
|
|
511
514
|
return self.matrix()
|
|
512
515
|
|
|
513
|
-
def _apply_unitary_(self, args:
|
|
516
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs):
|
|
514
517
|
if not self._has_unitary_():
|
|
515
518
|
return None
|
|
516
519
|
assert isinstance(self.coefficient, numbers.Complex)
|
|
@@ -738,7 +741,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
738
741
|
return float(np.real(result * self.coefficient))
|
|
739
742
|
|
|
740
743
|
def zip_items(
|
|
741
|
-
self, other:
|
|
744
|
+
self, other: cirq.PauliString[TKey]
|
|
742
745
|
) -> Iterator[Tuple[TKey, Tuple[pauli_gates.Pauli, pauli_gates.Pauli]]]:
|
|
743
746
|
"""Combines pauli operations from pauli strings in a qubit-by-qubit fashion.
|
|
744
747
|
|
|
@@ -757,7 +760,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
757
760
|
yield qubit, (pauli0, other[qubit])
|
|
758
761
|
|
|
759
762
|
def zip_paulis(
|
|
760
|
-
self, other:
|
|
763
|
+
self, other: cirq.PauliString
|
|
761
764
|
) -> Iterator[Tuple[pauli_gates.Pauli, pauli_gates.Pauli]]:
|
|
762
765
|
"""Combines pauli operations from pauli strings in a qubit-by-qubit fashion.
|
|
763
766
|
|
|
@@ -780,10 +783,10 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
780
783
|
return NotImplemented
|
|
781
784
|
return sum(not protocols.commutes(p0, p1) for p0, p1 in self.zip_paulis(other)) % 2 == 0
|
|
782
785
|
|
|
783
|
-
def __neg__(self) ->
|
|
786
|
+
def __neg__(self) -> PauliString:
|
|
784
787
|
return PauliString(qubit_pauli_map=self._qubit_pauli_map, coefficient=-self._coefficient)
|
|
785
788
|
|
|
786
|
-
def __pos__(self) ->
|
|
789
|
+
def __pos__(self) -> PauliString:
|
|
787
790
|
return self
|
|
788
791
|
|
|
789
792
|
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
|
|
@@ -861,7 +864,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
861
864
|
)
|
|
862
865
|
return NotImplemented
|
|
863
866
|
|
|
864
|
-
def map_qubits(self, qubit_map: Dict[TKey, TKeyNew]) ->
|
|
867
|
+
def map_qubits(self, qubit_map: Dict[TKey, TKeyNew]) -> cirq.PauliString[TKeyNew]:
|
|
865
868
|
"""Replaces every qubit `q` in `self.qubits` with `qubit_map[q]`.
|
|
866
869
|
|
|
867
870
|
Args:
|
|
@@ -888,7 +891,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
888
891
|
{pauli: (pauli_gates.Z, False)}
|
|
889
892
|
)(qubit)
|
|
890
893
|
|
|
891
|
-
def dense(self, qubits: Sequence[TKey]) ->
|
|
894
|
+
def dense(self, qubits: Sequence[TKey]) -> cirq.DensePauliString:
|
|
892
895
|
"""Returns a `cirq.DensePauliString` version of this Pauli string.
|
|
893
896
|
|
|
894
897
|
This method satisfies the invariant `P.dense(qubits).on(*qubits) == P`.
|
|
@@ -915,7 +918,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
915
918
|
# pylint: enable=too-many-function-args
|
|
916
919
|
return dense_pauli_string.DensePauliString(pauli_mask, coefficient=self.coefficient)
|
|
917
920
|
|
|
918
|
-
def conjugated_by(self, clifford:
|
|
921
|
+
def conjugated_by(self, clifford: cirq.OP_TREE) -> PauliString:
|
|
919
922
|
r"""Returns the Pauli string conjugated by a clifford operation.
|
|
920
923
|
|
|
921
924
|
The product-of-Paulis $P$ conjugated by the Clifford operation $C$ is
|
|
@@ -987,12 +990,12 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
987
990
|
# Then the conjugation = (C^{-1}⊗I·Pc⊗R·C⊗I) = (C^{-1}·Pc·C)⊗R.
|
|
988
991
|
|
|
989
992
|
# Isolate R
|
|
990
|
-
remain:
|
|
993
|
+
remain: cirq.PauliString = PauliString(
|
|
991
994
|
*(pauli(q) for q in all_qubits - set(op.qubits) if (pauli := ps.get(q)) is not None)
|
|
992
995
|
)
|
|
993
996
|
|
|
994
997
|
# Initialize the conjugation of Pc.
|
|
995
|
-
conjugated:
|
|
998
|
+
conjugated: cirq.DensePauliString = (
|
|
996
999
|
dense_pauli_string.DensePauliString(pauli_mask=[identity.I for _ in op.qubits])
|
|
997
1000
|
* ps.coefficient
|
|
998
1001
|
)
|
|
@@ -1000,7 +1003,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1000
1003
|
# Calculate the conjugation via CliffordGate's clifford_tableau.
|
|
1001
1004
|
# Note the clifford_tableau in CliffordGate represents C·P·C^-1 instead of C^-1·P·C.
|
|
1002
1005
|
# So we take the inverse of the tableau to match the definition of the conjugation here.
|
|
1003
|
-
gate_in_clifford:
|
|
1006
|
+
gate_in_clifford: cirq.CliffordGate
|
|
1004
1007
|
if isinstance(op.gate, clifford_gate.CliffordGate):
|
|
1005
1008
|
gate_in_clifford = op.gate
|
|
1006
1009
|
else:
|
|
@@ -1035,7 +1038,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1035
1038
|
ps = remain * conjugated.on(*op.qubits)
|
|
1036
1039
|
return ps
|
|
1037
1040
|
|
|
1038
|
-
def after(self, ops:
|
|
1041
|
+
def after(self, ops: cirq.OP_TREE) -> cirq.PauliString:
|
|
1039
1042
|
r"""Determines the equivalent pauli string after some operations.
|
|
1040
1043
|
|
|
1041
1044
|
If the PauliString is $P$ and the Clifford operation is $C$, then the
|
|
@@ -1051,7 +1054,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1051
1054
|
"""
|
|
1052
1055
|
return self.conjugated_by(protocols.inverse(ops))
|
|
1053
1056
|
|
|
1054
|
-
def before(self, ops:
|
|
1057
|
+
def before(self, ops: cirq.OP_TREE) -> cirq.PauliString:
|
|
1055
1058
|
r"""Determines the equivalent pauli string before some operations.
|
|
1056
1059
|
|
|
1057
1060
|
If the PauliString is $P$ and the Clifford operation is $C$, then the
|
|
@@ -1068,8 +1071,8 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1068
1071
|
return self.conjugated_by(ops)
|
|
1069
1072
|
|
|
1070
1073
|
def pass_operations_over(
|
|
1071
|
-
self, ops: Iterable[
|
|
1072
|
-
) ->
|
|
1074
|
+
self, ops: Iterable[cirq.Operation], after_to_before: bool = False
|
|
1075
|
+
) -> PauliString:
|
|
1073
1076
|
"""Determines how the Pauli string changes when conjugated by Cliffords.
|
|
1074
1077
|
|
|
1075
1078
|
The output and input pauli strings are related by a circuit equivalence.
|
|
@@ -1115,8 +1118,8 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1115
1118
|
return protocols.parameter_names(self.coefficient)
|
|
1116
1119
|
|
|
1117
1120
|
def _resolve_parameters_(
|
|
1118
|
-
self, resolver:
|
|
1119
|
-
) ->
|
|
1121
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
1122
|
+
) -> cirq.PauliString:
|
|
1120
1123
|
coefficient = protocols.resolve_parameters(self.coefficient, resolver, recursive)
|
|
1121
1124
|
return PauliString(qubit_pauli_map=self._qubit_pauli_map, coefficient=coefficient)
|
|
1122
1125
|
|
|
@@ -1189,11 +1192,11 @@ class SingleQubitPauliStringGateOperation( # type: ignore
|
|
|
1189
1192
|
GateOperation(X, [q]).
|
|
1190
1193
|
"""
|
|
1191
1194
|
|
|
1192
|
-
def __init__(self, pauli: pauli_gates.Pauli, qubit:
|
|
1195
|
+
def __init__(self, pauli: pauli_gates.Pauli, qubit: cirq.Qid):
|
|
1193
1196
|
PauliString.__init__(self, qubit_pauli_map={qubit: pauli})
|
|
1194
1197
|
gate_operation.GateOperation.__init__(self, cast(raw_types.Gate, pauli), [qubit])
|
|
1195
1198
|
|
|
1196
|
-
def with_qubits(self, *new_qubits:
|
|
1199
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> SingleQubitPauliStringGateOperation:
|
|
1197
1200
|
if len(new_qubits) != 1:
|
|
1198
1201
|
raise ValueError("len(new_qubits) != 1")
|
|
1199
1202
|
return SingleQubitPauliStringGateOperation(
|
|
@@ -1235,9 +1238,7 @@ class SingleQubitPauliStringGateOperation( # type: ignore
|
|
|
1235
1238
|
return protocols.obj_to_dict_helper(self, ['pauli', 'qubit'])
|
|
1236
1239
|
|
|
1237
1240
|
@classmethod
|
|
1238
|
-
def _from_json_dict_( # type: ignore
|
|
1239
|
-
cls, pauli: pauli_gates.Pauli, qubit: 'cirq.Qid', **kwargs
|
|
1240
|
-
):
|
|
1241
|
+
def _from_json_dict_(cls, pauli: pauli_gates.Pauli, qubit: cirq.Qid, **kwargs): # type: ignore
|
|
1241
1242
|
# Note, this method is required or else superclasses' deserialization
|
|
1242
1243
|
# would be used
|
|
1243
1244
|
return cls(pauli=pauli, qubit=qubit)
|
|
@@ -1258,8 +1259,8 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1258
1259
|
|
|
1259
1260
|
def __init__(
|
|
1260
1261
|
self,
|
|
1261
|
-
*contents:
|
|
1262
|
-
coefficient:
|
|
1262
|
+
*contents: cirq.PAULI_STRING_LIKE,
|
|
1263
|
+
coefficient: cirq.TParamValComplex = 1,
|
|
1263
1264
|
pauli_int_dict: Optional[Dict[TKey, int]] = None,
|
|
1264
1265
|
):
|
|
1265
1266
|
"""Initializes a new `MutablePauliString`.
|
|
@@ -1282,7 +1283,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1282
1283
|
Raises:
|
|
1283
1284
|
ValueError: If the `pauli_int_dict` has integer values `v` not satisfying `1 <= v <= 3`.
|
|
1284
1285
|
"""
|
|
1285
|
-
self.coefficient: Union[sympy.Expr,
|
|
1286
|
+
self.coefficient: Union[sympy.Expr, cirq.TParamValComplex] = (
|
|
1286
1287
|
coefficient if isinstance(coefficient, sympy.Expr) else complex(coefficient)
|
|
1287
1288
|
)
|
|
1288
1289
|
if pauli_int_dict is not None:
|
|
@@ -1314,7 +1315,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1314
1315
|
"""Returns the sequence of qubits on which this pauli string acts."""
|
|
1315
1316
|
return self.pauli_int_dict.keys()
|
|
1316
1317
|
|
|
1317
|
-
def values(self) -> Iterator[
|
|
1318
|
+
def values(self) -> Iterator[cirq.Pauli]:
|
|
1318
1319
|
"""Ordered sequence of `cirq.Pauli` gates acting on `self.keys()`."""
|
|
1319
1320
|
for v in self.pauli_int_dict.values():
|
|
1320
1321
|
yield _INT_TO_PAULI[v - 1]
|
|
@@ -1328,7 +1329,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1328
1329
|
def __bool__(self) -> bool:
|
|
1329
1330
|
return bool(self.pauli_int_dict)
|
|
1330
1331
|
|
|
1331
|
-
def frozen(self) ->
|
|
1332
|
+
def frozen(self) -> cirq.PauliString:
|
|
1332
1333
|
"""Returns a `cirq.PauliString` with the same contents.
|
|
1333
1334
|
|
|
1334
1335
|
For example, this is useful because `cirq.PauliString` is an operation
|
|
@@ -1339,13 +1340,13 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1339
1340
|
qubit_pauli_map={q: _INT_TO_PAULI[p - 1] for q, p in self.pauli_int_dict.items() if p},
|
|
1340
1341
|
)
|
|
1341
1342
|
|
|
1342
|
-
def mutable_copy(self) ->
|
|
1343
|
+
def mutable_copy(self) -> cirq.MutablePauliString:
|
|
1343
1344
|
"""Returns a new `cirq.MutablePauliString` with the same contents."""
|
|
1344
1345
|
return MutablePauliString(
|
|
1345
1346
|
coefficient=self.coefficient, pauli_int_dict=dict(self.pauli_int_dict)
|
|
1346
1347
|
)
|
|
1347
1348
|
|
|
1348
|
-
def items(self) -> Iterator[Tuple[TKey,
|
|
1349
|
+
def items(self) -> Iterator[Tuple[TKey, cirq.Pauli]]:
|
|
1349
1350
|
"""Returns (cirq.Qid, cirq.Pauli) pairs representing 1-qubit operations of pauli string."""
|
|
1350
1351
|
for k, v in self.pauli_int_dict.items():
|
|
1351
1352
|
yield k, _INT_TO_PAULI[v - 1]
|
|
@@ -1353,10 +1354,10 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1353
1354
|
def __contains__(self, item: Any) -> bool:
|
|
1354
1355
|
return item in self.pauli_int_dict
|
|
1355
1356
|
|
|
1356
|
-
def __getitem__(self, item: Any) ->
|
|
1357
|
+
def __getitem__(self, item: Any) -> cirq.Pauli:
|
|
1357
1358
|
return _INT_TO_PAULI[self.pauli_int_dict[item] - 1]
|
|
1358
1359
|
|
|
1359
|
-
def __setitem__(self, key: TKey, value:
|
|
1360
|
+
def __setitem__(self, key: TKey, value: cirq.PAULI_GATE_LIKE):
|
|
1360
1361
|
value = _pauli_like_to_pauli_int(key, value)
|
|
1361
1362
|
if value:
|
|
1362
1363
|
self.pauli_int_dict[key] = _pauli_like_to_pauli_int(key, value)
|
|
@@ -1368,20 +1369,20 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1368
1369
|
|
|
1369
1370
|
# pylint: disable=function-redefined
|
|
1370
1371
|
@overload
|
|
1371
|
-
def get(self, key: TKey, default: None = None) -> Union[
|
|
1372
|
+
def get(self, key: TKey, default: None = None) -> Union[cirq.Pauli, None]:
|
|
1372
1373
|
pass
|
|
1373
1374
|
|
|
1374
1375
|
@overload
|
|
1375
|
-
def get(self, key: TKey, default: TDefault) -> Union[
|
|
1376
|
+
def get(self, key: TKey, default: TDefault) -> Union[cirq.Pauli, TDefault]:
|
|
1376
1377
|
pass
|
|
1377
1378
|
|
|
1378
|
-
def get(self, key: TKey, default=None) -> Union[
|
|
1379
|
+
def get(self, key: TKey, default=None) -> Union[cirq.Pauli, TDefault, None]:
|
|
1379
1380
|
"""Returns the `cirq.Pauli` operation acting on qubit `key` or `default` if none exists."""
|
|
1380
1381
|
result = self.pauli_int_dict.get(key, None)
|
|
1381
1382
|
return default if result is None else _INT_TO_PAULI[result - 1]
|
|
1382
1383
|
|
|
1383
1384
|
# pylint: enable=function-redefined
|
|
1384
|
-
def inplace_before(self, ops:
|
|
1385
|
+
def inplace_before(self, ops: cirq.OP_TREE) -> cirq.MutablePauliString:
|
|
1385
1386
|
r"""Propagates the pauli string from after to before a Clifford effect.
|
|
1386
1387
|
|
|
1387
1388
|
If the old value of the MutablePauliString is $P$ and the Clifford
|
|
@@ -1397,7 +1398,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1397
1398
|
"""
|
|
1398
1399
|
return self.inplace_after(protocols.inverse(ops))
|
|
1399
1400
|
|
|
1400
|
-
def inplace_after(self, ops:
|
|
1401
|
+
def inplace_after(self, ops: cirq.OP_TREE) -> cirq.MutablePauliString:
|
|
1401
1402
|
r"""Propagates the pauli string from before to after a Clifford effect.
|
|
1402
1403
|
|
|
1403
1404
|
If the old value of the MutablePauliString is $P$ and the Clifford
|
|
@@ -1453,7 +1454,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1453
1454
|
raise NotImplementedError(f"Unrecognized decomposed Clifford: {op!r}")
|
|
1454
1455
|
return self
|
|
1455
1456
|
|
|
1456
|
-
def _imul_helper(self, other:
|
|
1457
|
+
def _imul_helper(self, other: cirq.PAULI_STRING_LIKE, sign: int):
|
|
1457
1458
|
"""Left-multiplies or right-multiplies by a PAULI_STRING_LIKE.
|
|
1458
1459
|
|
|
1459
1460
|
Args:
|
|
@@ -1492,7 +1493,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1492
1493
|
|
|
1493
1494
|
return self
|
|
1494
1495
|
|
|
1495
|
-
def _imul_helper_checkpoint(self, other:
|
|
1496
|
+
def _imul_helper_checkpoint(self, other: cirq.PAULI_STRING_LIKE, sign: int):
|
|
1496
1497
|
"""Like `_imul_helper` but guarantees no-op on error."""
|
|
1497
1498
|
|
|
1498
1499
|
if not isinstance(other, (numbers.Number, PauliString, MutablePauliString)):
|
|
@@ -1501,9 +1502,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1501
1502
|
return NotImplemented
|
|
1502
1503
|
return self._imul_helper(other, sign)
|
|
1503
1504
|
|
|
1504
|
-
def inplace_left_multiply_by(
|
|
1505
|
-
self, other: 'cirq.PAULI_STRING_LIKE'
|
|
1506
|
-
) -> 'cirq.MutablePauliString':
|
|
1505
|
+
def inplace_left_multiply_by(self, other: cirq.PAULI_STRING_LIKE) -> cirq.MutablePauliString:
|
|
1507
1506
|
"""Left-multiplies a pauli string into this pauli string.
|
|
1508
1507
|
|
|
1509
1508
|
Args:
|
|
@@ -1532,9 +1531,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1532
1531
|
def _from_json_dict_(cls, pauli_int_dict, coefficient, **kwargs):
|
|
1533
1532
|
return cls(pauli_int_dict=dict(pauli_int_dict), coefficient=coefficient)
|
|
1534
1533
|
|
|
1535
|
-
def inplace_right_multiply_by(
|
|
1536
|
-
self, other: 'cirq.PAULI_STRING_LIKE'
|
|
1537
|
-
) -> 'cirq.MutablePauliString':
|
|
1534
|
+
def inplace_right_multiply_by(self, other: cirq.PAULI_STRING_LIKE) -> cirq.MutablePauliString:
|
|
1538
1535
|
"""Right-multiplies a pauli string into this pauli string.
|
|
1539
1536
|
|
|
1540
1537
|
Args:
|
|
@@ -1552,17 +1549,17 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1552
1549
|
raise TypeError(f"{other!r} is not cirq.PAULI_STRING_LIKE.")
|
|
1553
1550
|
return self
|
|
1554
1551
|
|
|
1555
|
-
def __neg__(self) ->
|
|
1552
|
+
def __neg__(self) -> cirq.MutablePauliString:
|
|
1556
1553
|
result = self.mutable_copy()
|
|
1557
1554
|
result.coefficient *= -1
|
|
1558
1555
|
return result
|
|
1559
1556
|
|
|
1560
|
-
def __pos__(self) ->
|
|
1557
|
+
def __pos__(self) -> cirq.MutablePauliString:
|
|
1561
1558
|
return self.mutable_copy()
|
|
1562
1559
|
|
|
1563
1560
|
def transform_qubits(
|
|
1564
1561
|
self, func: Callable[[TKey], TKeyNew], *, inplace: bool = False
|
|
1565
|
-
) ->
|
|
1562
|
+
) -> cirq.MutablePauliString[TKeyNew]:
|
|
1566
1563
|
"""Returns a `MutablePauliString` with transformed qubits.
|
|
1567
1564
|
|
|
1568
1565
|
Args:
|
|
@@ -1585,7 +1582,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1585
1582
|
result.pauli_int_dict = new_dict
|
|
1586
1583
|
return result
|
|
1587
1584
|
|
|
1588
|
-
def __imul__(self, other:
|
|
1585
|
+
def __imul__(self, other: cirq.PAULI_STRING_LIKE) -> cirq.MutablePauliString:
|
|
1589
1586
|
"""Left-multiplies a pauli string into this pauli string.
|
|
1590
1587
|
|
|
1591
1588
|
Args:
|
|
@@ -1601,14 +1598,14 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1601
1598
|
"""
|
|
1602
1599
|
return self._imul_helper_checkpoint(other, +1)
|
|
1603
1600
|
|
|
1604
|
-
def __mul__(self, other:
|
|
1601
|
+
def __mul__(self, other: cirq.PAULI_STRING_LIKE) -> cirq.PauliString:
|
|
1605
1602
|
"""Multiplies two pauli-string-likes together.
|
|
1606
1603
|
|
|
1607
1604
|
The result is not mutable.
|
|
1608
1605
|
"""
|
|
1609
1606
|
return self.frozen() * other
|
|
1610
1607
|
|
|
1611
|
-
def __rmul__(self, other:
|
|
1608
|
+
def __rmul__(self, other: cirq.PAULI_STRING_LIKE) -> cirq.PauliString:
|
|
1612
1609
|
"""Multiplies two pauli-string-likes together.
|
|
1613
1610
|
|
|
1614
1611
|
The result is not mutable.
|
|
@@ -1622,7 +1619,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1622
1619
|
return f'{self.frozen()!r}.mutable_copy()'
|
|
1623
1620
|
|
|
1624
1621
|
|
|
1625
|
-
def _decompose_into_cliffords(op:
|
|
1622
|
+
def _decompose_into_cliffords(op: cirq.Operation) -> List[cirq.Operation]:
|
|
1626
1623
|
# An operation that can be ignored?
|
|
1627
1624
|
if isinstance(op.gate, global_phase_op.GlobalPhaseGate):
|
|
1628
1625
|
return []
|
|
@@ -1657,7 +1654,7 @@ _x = cast(pauli_gates.Pauli, pauli_gates.X) # type: ignore
|
|
|
1657
1654
|
_y = cast(pauli_gates.Pauli, pauli_gates.Y) # type: ignore
|
|
1658
1655
|
_z = cast(pauli_gates.Pauli, pauli_gates.Z) # type: ignore
|
|
1659
1656
|
|
|
1660
|
-
PAULI_GATE_LIKE_TO_INDEX_MAP: Dict[
|
|
1657
|
+
PAULI_GATE_LIKE_TO_INDEX_MAP: Dict[cirq.PAULI_GATE_LIKE, int] = {
|
|
1661
1658
|
_i: 0,
|
|
1662
1659
|
_x: 1,
|
|
1663
1660
|
_y: 2,
|
|
@@ -1676,13 +1673,13 @@ PAULI_GATE_LIKE_TO_INDEX_MAP: Dict['cirq.PAULI_GATE_LIKE', int] = {
|
|
|
1676
1673
|
3: 3,
|
|
1677
1674
|
}
|
|
1678
1675
|
|
|
1679
|
-
_INT_TO_PAULI_OR_IDENTITY: List[Union[
|
|
1680
|
-
_INT_TO_PAULI: List[
|
|
1676
|
+
_INT_TO_PAULI_OR_IDENTITY: List[Union[cirq.Pauli, cirq.IdentityGate]] = [_i, _x, _y, _z]
|
|
1677
|
+
_INT_TO_PAULI: List[cirq.Pauli] = [_x, _y, _z]
|
|
1681
1678
|
|
|
1682
1679
|
|
|
1683
|
-
PAULI_GATE_LIKE_TO_GATE_MAP: Dict[
|
|
1684
|
-
|
|
1685
|
-
|
|
1680
|
+
PAULI_GATE_LIKE_TO_GATE_MAP: Dict[cirq.PAULI_GATE_LIKE, Union[cirq.Pauli, cirq.IdentityGate]] = {
|
|
1681
|
+
k: _INT_TO_PAULI_OR_IDENTITY[v] for k, v in PAULI_GATE_LIKE_TO_INDEX_MAP.items()
|
|
1682
|
+
}
|
|
1686
1683
|
|
|
1687
1684
|
|
|
1688
1685
|
def _pauli_like_to_pauli_int(key: Any, pauli_gate_like: PAULI_GATE_LIKE):
|