cirq-core 1.5.0.dev20250226233318__py3-none-any.whl → 1.5.0.dev20250228014434__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/clifford_gate.py +5 -2
- cirq/ops/pauli_string.py +64 -13
- cirq/ops/pauli_string_test.py +70 -49
- cirq/ops/swap_gates.py +5 -0
- cirq/transformers/dynamical_decoupling.py +8 -12
- {cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/METADATA +1 -1
- {cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/RECORD +12 -12
- {cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/WHEEL +0 -0
- {cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/top_level.txt +0 -0
cirq/_version.py
CHANGED
cirq/_version_test.py
CHANGED
cirq/ops/clifford_gate.py
CHANGED
|
@@ -377,7 +377,10 @@ class CliffordGate(raw_types.Gate, CommonCliffordGates):
|
|
|
377
377
|
# ZI [ 0 0 | 1 0 | 1 ]
|
|
378
378
|
# IZ [ 1 0 | 1 1 | 0 ]
|
|
379
379
|
# Take the third row as example: this means the ZI gate after the this gate,
|
|
380
|
-
# more precisely the conjugate transformation of ZI by this gate, becomes -ZI
|
|
380
|
+
# more precisely the conjugate transformation of ZI by this gate, becomes -ZI:
|
|
381
|
+
# ---(CliffordGate^-1)---ZI---CliffordGate---
|
|
382
|
+
# = unitary(CliffordGate)@unitary(ZI)@unitary(CliffordGate).conj().T
|
|
383
|
+
# = -ZI.
|
|
381
384
|
# (Note the real clifford tableau has to satify the Symplectic property.
|
|
382
385
|
# here is just for illustration)
|
|
383
386
|
object.__setattr__(self, '_clifford_tableau', _clifford_tableau.copy())
|
|
@@ -438,7 +441,7 @@ class CliffordGate(raw_types.Gate, CommonCliffordGates):
|
|
|
438
441
|
def _commutes_(
|
|
439
442
|
self, other: Any, *, atol: float = 1e-8
|
|
440
443
|
) -> Union[bool, NotImplementedType, None]:
|
|
441
|
-
# Note even if we assume two gates define the
|
|
444
|
+
# Note even if we assume two gates define the tableau based on the same qubit order,
|
|
442
445
|
# the following approach cannot judge it:
|
|
443
446
|
# self.clifford_tableau.then(other.clifford_tableau) == other.clifford_tableau.then(
|
|
444
447
|
# self.clifford_tableau
|
cirq/ops/pauli_string.py
CHANGED
|
@@ -55,6 +55,7 @@ from cirq.ops import (
|
|
|
55
55
|
pauli_gates,
|
|
56
56
|
pauli_interaction_gate,
|
|
57
57
|
raw_types,
|
|
58
|
+
dense_pauli_string,
|
|
58
59
|
)
|
|
59
60
|
|
|
60
61
|
if TYPE_CHECKING:
|
|
@@ -907,14 +908,13 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
907
908
|
Raises:
|
|
908
909
|
ValueError: If the number of qubits is too small.
|
|
909
910
|
"""
|
|
910
|
-
from cirq.ops.dense_pauli_string import DensePauliString
|
|
911
911
|
|
|
912
912
|
if not self.keys() <= set(qubits):
|
|
913
913
|
raise ValueError('not self.keys() <= set(qubits)')
|
|
914
914
|
# pylint: disable=too-many-function-args
|
|
915
915
|
pauli_mask = [self.get(q, identity.I) for q in qubits]
|
|
916
916
|
# pylint: enable=too-many-function-args
|
|
917
|
-
return DensePauliString(pauli_mask, coefficient=self.coefficient)
|
|
917
|
+
return dense_pauli_string.DensePauliString(pauli_mask, coefficient=self.coefficient)
|
|
918
918
|
|
|
919
919
|
def conjugated_by(self, clifford: 'cirq.OP_TREE') -> 'PauliString':
|
|
920
920
|
r"""Returns the Pauli string conjugated by a clifford operation.
|
|
@@ -976,17 +976,68 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
976
976
|
Returns:
|
|
977
977
|
The Pauli string conjugated by the given Clifford operation.
|
|
978
978
|
"""
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
979
|
+
|
|
980
|
+
# Initialize the ps the same as self.
|
|
981
|
+
ps = PauliString(qubit_pauli_map=self._qubit_pauli_map, coefficient=self.coefficient)
|
|
982
|
+
all_ops = list(op_tree.flatten_to_ops(clifford))
|
|
983
|
+
all_qubits = set.union(set(self.qubits), [q for op in all_ops for q in op.qubits])
|
|
984
|
+
|
|
985
|
+
# Iteratively calculate the conjugation in reverse order of ops.
|
|
986
|
+
for op in all_ops[::-1]:
|
|
987
|
+
# To calcuate the conjugation of P (`ps`) with respect to C (`op`)
|
|
988
|
+
# Decompose P = Pc⊗R, where Pc acts on the same qubits as C, R acts on the remaining.
|
|
989
|
+
# Then the conjugation = (C^{-1}⊗I·Pc⊗R·C⊗I) = (C^{-1}·Pc·C)⊗R.
|
|
990
|
+
|
|
991
|
+
# Isolate R
|
|
992
|
+
remain: 'cirq.PauliString' = PauliString()
|
|
993
|
+
for q in all_qubits:
|
|
994
|
+
pauli = ps.get(q)
|
|
995
|
+
if pauli is not None and not q in op.qubits:
|
|
996
|
+
remain *= pauli(q)
|
|
997
|
+
|
|
998
|
+
# Initialize the conjugation of Pc.
|
|
999
|
+
conjugated: 'cirq.DensePauliString' = (
|
|
1000
|
+
dense_pauli_string.DensePauliString(pauli_mask=[identity.I for _ in op.qubits])
|
|
1001
|
+
* self.coefficient
|
|
1002
|
+
)
|
|
1003
|
+
|
|
1004
|
+
# Calculate the conjugation via CliffordGate's clifford_tableau.
|
|
1005
|
+
# Note the clifford_tableau in CliffordGate represents C·P·C^-1 instead of C^-1·P·C.
|
|
1006
|
+
# So we take the inverse of the tableau to match the definition of the conjugation here.
|
|
1007
|
+
gate_in_clifford: 'cirq.CliffordGate'
|
|
1008
|
+
if isinstance(op.gate, cirq.CliffordGate):
|
|
1009
|
+
gate_in_clifford = op.gate
|
|
1010
|
+
else:
|
|
1011
|
+
# Convert the clifford gate to CliffordGate type.
|
|
1012
|
+
gate_in_clifford = clifford_gate.CliffordGate.from_op_list([op], op.qubits)
|
|
1013
|
+
tableau = gate_in_clifford.clifford_tableau.inverse()
|
|
1014
|
+
|
|
1015
|
+
# Calculate the conjugation by `op` via mutiplying the conjugation of each Pauli:
|
|
1016
|
+
# C^{-1}·(P_1⊗...⊗P_n)·C
|
|
1017
|
+
# = C^{-1}·(P_1⊗I) ...·(P_n⊗I)·C
|
|
1018
|
+
# = (C^{-1}(P_1⊗I)C)·...·(C^{-1}(P_n⊗I)C)
|
|
1019
|
+
# For the Pauli on the kth qubit P_k. The conjugation is calculated as following.
|
|
1020
|
+
# Puali X_k's conjugation is from the destabilzer table;
|
|
1021
|
+
# Puali Z_k's conjugation is from the stabilzer table;
|
|
1022
|
+
# Puali Y_k's conjugation is calcluated according to Y = iXZ. E.g., for the kth qubit,
|
|
1023
|
+
# C^{-1}·Y_k⊗I·C = C^{-1}·(iX_k⊗I·Z_k⊗I)·C = i (C^{-1}·X_k⊗I·C)·(C^{-1}·Z_k⊗I·C)
|
|
1024
|
+
for qid, qubit in enumerate(op.qubits):
|
|
1025
|
+
pauli = ps.get(qubit)
|
|
1026
|
+
match pauli:
|
|
1027
|
+
case None:
|
|
1028
|
+
continue
|
|
1029
|
+
case pauli_gates.X:
|
|
1030
|
+
conjugated *= tableau.destabilizers()[qid]
|
|
1031
|
+
case pauli_gates.Z:
|
|
1032
|
+
conjugated *= tableau.stabilizers()[qid]
|
|
1033
|
+
case pauli_gates.Y:
|
|
1034
|
+
conjugated *= (
|
|
1035
|
+
1j
|
|
1036
|
+
* tableau.destabilizers()[qid] # conj X first
|
|
1037
|
+
* tableau.stabilizers()[qid] # then conj Z
|
|
1038
|
+
)
|
|
1039
|
+
ps = remain * conjugated.on(*op.qubits)
|
|
1040
|
+
return ps
|
|
990
1041
|
|
|
991
1042
|
def after(self, ops: 'cirq.OP_TREE') -> 'cirq.PauliString':
|
|
992
1043
|
r"""Determines the equivalent pauli string after some operations.
|
cirq/ops/pauli_string_test.py
CHANGED
|
@@ -57,6 +57,22 @@ def _small_sample_qubit_pauli_maps():
|
|
|
57
57
|
yield {qubits[0]: cirq.Z, qubits[1]: cirq.X, qubits[2]: cirq.Y}
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
def assert_conjugation(
|
|
61
|
+
input_ps: cirq.PauliString, ops: cirq.OP_TREE, expected: cirq.PauliString | None
|
|
62
|
+
):
|
|
63
|
+
conjugation = input_ps.conjugated_by(ops)
|
|
64
|
+
if expected is not None:
|
|
65
|
+
assert conjugation == expected
|
|
66
|
+
else: # Compares the unitary of the conjugation result and the expected unitary.
|
|
67
|
+
op_list = list(cirq.flatten_to_ops(ops))
|
|
68
|
+
qubits_of_clifford = [q for op in op_list for q in op.qubits]
|
|
69
|
+
clifford = cirq.CliffordGate.from_op_list(op_list, qubits_of_clifford)
|
|
70
|
+
actual_unitary = cirq.unitary(conjugation.dense(qubits_of_clifford))
|
|
71
|
+
c = cirq.unitary(clifford)
|
|
72
|
+
expected_unitary = np.conj(c.T) @ cirq.unitary(input_ps.dense(qubits_of_clifford)) @ c
|
|
73
|
+
assert np.allclose(actual_unitary, expected_unitary, atol=1e-8)
|
|
74
|
+
|
|
75
|
+
|
|
60
76
|
def test_eq_ne_hash():
|
|
61
77
|
q0, q1, q2 = _make_qubits(3)
|
|
62
78
|
eq = cirq.testing.EqualsTester()
|
|
@@ -1381,13 +1397,24 @@ def test_pauli_string_expectation_from_state_vector_mixed_state_linearity():
|
|
|
1381
1397
|
def test_conjugated_by_normal_gates():
|
|
1382
1398
|
a = cirq.LineQubit(0)
|
|
1383
1399
|
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1400
|
+
assert_conjugation(cirq.X(a), cirq.H(a), cirq.Z(a))
|
|
1401
|
+
assert_conjugation(cirq.Y(a), cirq.H(a), -cirq.Y(a))
|
|
1402
|
+
assert_conjugation(cirq.Z(a), cirq.H(a), cirq.X(a))
|
|
1403
|
+
|
|
1404
|
+
assert_conjugation(cirq.X(a), cirq.S(a), -cirq.Y(a))
|
|
1405
|
+
assert_conjugation(cirq.Y(a), cirq.S(a), cirq.X(a))
|
|
1406
|
+
assert_conjugation(cirq.Z(a), cirq.S(a), cirq.Z(a))
|
|
1407
|
+
|
|
1408
|
+
clifford_op = cirq.PhasedXZGate(axis_phase_exponent=0.25, x_exponent=-1, z_exponent=0).on(a)
|
|
1409
|
+
assert_conjugation(cirq.X(a), clifford_op, cirq.Y(a))
|
|
1410
|
+
assert_conjugation(cirq.Y(a), clifford_op, cirq.X(a))
|
|
1411
|
+
assert_conjugation(cirq.Z(a), clifford_op, -cirq.Z(a))
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
def test_conjugated_by_op_gate_of_clifford_gate_type():
|
|
1415
|
+
a = cirq.LineQubit(0)
|
|
1387
1416
|
|
|
1388
|
-
|
|
1389
|
-
assert cirq.Y(a).conjugated_by(cirq.S(a)) == cirq.X(a)
|
|
1390
|
-
assert cirq.Z(a).conjugated_by(cirq.S(a)) == cirq.Z(a)
|
|
1417
|
+
assert_conjugation(cirq.X(a), cirq.CliffordGate.from_op_list([cirq.H(a)], [a]).on(a), cirq.Z(a))
|
|
1391
1418
|
|
|
1392
1419
|
|
|
1393
1420
|
def test_dense():
|
|
@@ -1430,16 +1457,25 @@ def test_conjugated_by_incorrectly_powered_cliffords():
|
|
|
1430
1457
|
cirq.ZZ(a, b),
|
|
1431
1458
|
]
|
|
1432
1459
|
for c in cliffords:
|
|
1433
|
-
with pytest.raises(
|
|
1460
|
+
with pytest.raises(
|
|
1461
|
+
ValueError,
|
|
1462
|
+
match='Clifford Gate can only be constructed from the operations'
|
|
1463
|
+
' that has stabilizer effect.',
|
|
1464
|
+
):
|
|
1434
1465
|
_ = p.conjugated_by(c**0.1)
|
|
1435
|
-
with pytest.raises(
|
|
1466
|
+
with pytest.raises(
|
|
1467
|
+
ValueError,
|
|
1468
|
+
match='Clifford Gate can only be constructed from the operations'
|
|
1469
|
+
' that has stabilizer effect.',
|
|
1470
|
+
):
|
|
1436
1471
|
_ = p.conjugated_by(c ** sympy.Symbol('t'))
|
|
1437
1472
|
|
|
1438
1473
|
|
|
1439
1474
|
def test_conjugated_by_global_phase():
|
|
1475
|
+
"""Global phase gate preserves PauliString."""
|
|
1440
1476
|
a = cirq.LineQubit(0)
|
|
1441
|
-
|
|
1442
|
-
|
|
1477
|
+
assert_conjugation(cirq.X(a), cirq.global_phase_operation(1j), cirq.X(a))
|
|
1478
|
+
assert_conjugation(cirq.X(a), cirq.global_phase_operation(np.exp(1.1j)), cirq.X(a))
|
|
1443
1479
|
|
|
1444
1480
|
class DecomposeGlobal(cirq.Gate):
|
|
1445
1481
|
def num_qubits(self):
|
|
@@ -1448,7 +1484,7 @@ def test_conjugated_by_global_phase():
|
|
|
1448
1484
|
def _decompose_(self, qubits):
|
|
1449
1485
|
yield cirq.global_phase_operation(1j)
|
|
1450
1486
|
|
|
1451
|
-
|
|
1487
|
+
assert_conjugation(cirq.X(a), DecomposeGlobal().on(a), cirq.X(a))
|
|
1452
1488
|
|
|
1453
1489
|
|
|
1454
1490
|
def test_conjugated_by_composite_with_disjoint_sub_gates():
|
|
@@ -1461,8 +1497,10 @@ def test_conjugated_by_composite_with_disjoint_sub_gates():
|
|
|
1461
1497
|
def _decompose_(self, qubits):
|
|
1462
1498
|
yield cirq.H(qubits[1])
|
|
1463
1499
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1500
|
+
for g1 in [cirq.X, cirq.Y]:
|
|
1501
|
+
for g2 in [cirq.X, cirq.Y]:
|
|
1502
|
+
ps = g1(a) * g2(b)
|
|
1503
|
+
assert ps.conjugated_by(DecomposeDisjoint().on(a, b)) == ps.conjugated_by(cirq.H(b))
|
|
1466
1504
|
|
|
1467
1505
|
|
|
1468
1506
|
def test_conjugated_by_clifford_composite():
|
|
@@ -1477,16 +1515,16 @@ def test_conjugated_by_clifford_composite():
|
|
|
1477
1515
|
yield cirq.SWAP(qubits[2], qubits[3])
|
|
1478
1516
|
|
|
1479
1517
|
a, b, c, d = cirq.LineQubit.range(4)
|
|
1480
|
-
|
|
1518
|
+
ps = cirq.X(a) * cirq.Z(b)
|
|
1481
1519
|
u = UnknownGate()
|
|
1482
|
-
|
|
1520
|
+
assert_conjugation(ps, u(a, b, c, d), cirq.Z(a) * cirq.X(b))
|
|
1483
1521
|
|
|
1484
1522
|
|
|
1485
1523
|
def test_conjugated_by_move_into_uninvolved():
|
|
1486
1524
|
a, b, c, d = cirq.LineQubit.range(4)
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1525
|
+
ps = cirq.X(a) * cirq.Z(b)
|
|
1526
|
+
assert_conjugation(ps, [cirq.SWAP(c, d), cirq.SWAP(b, c)], cirq.X(a) * cirq.Z(d))
|
|
1527
|
+
assert_conjugation(ps, [cirq.SWAP(b, c), cirq.SWAP(c, d)], cirq.X(a) * cirq.Z(c))
|
|
1490
1528
|
|
|
1491
1529
|
|
|
1492
1530
|
def test_conjugated_by_common_single_qubit_gates():
|
|
@@ -1508,21 +1546,13 @@ def test_conjugated_by_common_single_qubit_gates():
|
|
|
1508
1546
|
single_qubit_gates = [g**i for i in range(4) for g in base_single_qubit_gates]
|
|
1509
1547
|
for p in [cirq.X, cirq.Y, cirq.Z]:
|
|
1510
1548
|
for g in single_qubit_gates:
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
expected = np.conj(u.T) @ cirq.unitary(p) @ u
|
|
1516
|
-
assert cirq.allclose_up_to_global_phase(actual, expected, atol=1e-8)
|
|
1549
|
+
# pauli gate on a, clifford on b: pauli gate preserves.
|
|
1550
|
+
assert_conjugation(p(a), g(b), p(a))
|
|
1551
|
+
# pauli gate on a, clifford on a: check conjugation in matrices.
|
|
1552
|
+
assert_conjugation(p(a), g(a), None)
|
|
1517
1553
|
|
|
1518
1554
|
|
|
1519
1555
|
def test_conjugated_by_common_two_qubit_gates():
|
|
1520
|
-
class OrderSensitiveGate(cirq.Gate):
|
|
1521
|
-
def num_qubits(self):
|
|
1522
|
-
return 2
|
|
1523
|
-
|
|
1524
|
-
def _decompose_(self, qubits):
|
|
1525
|
-
return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
|
|
1526
1556
|
|
|
1527
1557
|
a, b, c, d = cirq.LineQubit.range(4)
|
|
1528
1558
|
two_qubit_gates = [
|
|
@@ -1541,34 +1571,25 @@ def test_conjugated_by_common_two_qubit_gates():
|
|
|
1541
1571
|
cirq.YY**-0.5,
|
|
1542
1572
|
cirq.ZZ**-0.5,
|
|
1543
1573
|
]
|
|
1544
|
-
two_qubit_gates.extend([OrderSensitiveGate()])
|
|
1545
1574
|
for p1 in [cirq.I, cirq.X, cirq.Y, cirq.Z]:
|
|
1546
1575
|
for p2 in [cirq.I, cirq.X, cirq.Y, cirq.Z]:
|
|
1547
1576
|
pd = cirq.DensePauliString([p1, p2])
|
|
1548
|
-
p = pd.sparse()
|
|
1577
|
+
p = pd.sparse([a, b])
|
|
1549
1578
|
for g in two_qubit_gates:
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
np.testing.assert_allclose(actual, expected, atol=1e-8)
|
|
1579
|
+
# pauli_string on (a,b), clifford on (c,d): pauli_string preserves.
|
|
1580
|
+
assert_conjugation(p, g(c, d), p)
|
|
1581
|
+
# pauli_string on (a,b), clifford on (a,b): compare unitaries of
|
|
1582
|
+
# the conjugated_by and actual matrix conjugation.
|
|
1583
|
+
assert_conjugation(p, g.on(a, b), None)
|
|
1556
1584
|
|
|
1557
1585
|
|
|
1558
1586
|
def test_conjugated_by_ordering():
|
|
1559
|
-
|
|
1560
|
-
def num_qubits(self):
|
|
1561
|
-
return 2
|
|
1562
|
-
|
|
1563
|
-
def _decompose_(self, qubits):
|
|
1564
|
-
return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
|
|
1565
|
-
|
|
1587
|
+
"""Tests .conjugated_by([op1, op2]) == .conjugated_by(op2).conjugated_by(op1)"""
|
|
1566
1588
|
a, b = cirq.LineQubit.range(2)
|
|
1567
1589
|
inp = cirq.Z(b)
|
|
1568
|
-
out1 = inp.conjugated_by(
|
|
1569
|
-
out2 = inp.conjugated_by(
|
|
1570
|
-
|
|
1571
|
-
assert out1 == out2 == out3 == cirq.X(a) * cirq.Z(b)
|
|
1590
|
+
out1 = inp.conjugated_by([cirq.H(a), cirq.CNOT(a, b)])
|
|
1591
|
+
out2 = inp.conjugated_by(cirq.CNOT(a, b)).conjugated_by(cirq.H(a))
|
|
1592
|
+
assert out1 == out2 == cirq.X(a) * cirq.Z(b)
|
|
1572
1593
|
|
|
1573
1594
|
|
|
1574
1595
|
def test_pass_operations_over_ordering():
|
cirq/ops/swap_gates.py
CHANGED
|
@@ -219,6 +219,11 @@ class ISwapPowGate(gate_features.InterchangeableQubitsGate, eigen_gate.EigenGate
|
|
|
219
219
|
]
|
|
220
220
|
# yapf: enable
|
|
221
221
|
|
|
222
|
+
def _has_stabilizer_effect_(self) -> Optional[bool]:
|
|
223
|
+
if self._is_parameterized_():
|
|
224
|
+
return None
|
|
225
|
+
return self.exponent % 1 == 0
|
|
226
|
+
|
|
222
227
|
def _decompose_(self, qubits):
|
|
223
228
|
a, b = qubits
|
|
224
229
|
|
|
@@ -58,6 +58,8 @@ def _pauli_up_to_global_phase(gate: ops.Gate) -> Union[ops.Pauli, None]:
|
|
|
58
58
|
def _validate_dd_sequence(dd_sequence: Tuple[ops.Gate, ...]) -> None:
|
|
59
59
|
"""Validates a given dynamical decoupling sequence.
|
|
60
60
|
|
|
61
|
+
The sequence should only consists of Pauli gates and is essentially an identity gate.
|
|
62
|
+
|
|
61
63
|
Args:
|
|
62
64
|
dd_sequence: Input dynamical sequence to be validated.
|
|
63
65
|
|
|
@@ -93,7 +95,7 @@ def _parse_dd_sequence(
|
|
|
93
95
|
_validate_dd_sequence(schema)
|
|
94
96
|
dd_sequence = schema
|
|
95
97
|
|
|
96
|
-
# Map
|
|
98
|
+
# Map gate to Pauli gate. This is necessary as dd sequence might contain gates like X^-1.
|
|
97
99
|
pauli_map: Dict[ops.Gate, ops.Pauli] = {}
|
|
98
100
|
for gate in dd_sequence:
|
|
99
101
|
pauli_gate = _pauli_up_to_global_phase(gate)
|
|
@@ -171,19 +173,13 @@ def _try_merge_single_qubit_ops_of_two_moments(
|
|
|
171
173
|
def _calc_pulled_through(
|
|
172
174
|
moment: circuits.Moment, input_pauli_ops: ops.PauliString
|
|
173
175
|
) -> ops.PauliString:
|
|
174
|
-
"""Calculates the pulled_through such that circuit(
|
|
176
|
+
"""Calculates the pulled_through such that circuit(input_pauli_ops, moment.clifford_ops) is
|
|
175
177
|
equivalent to circuit(moment.clifford_ops, pulled_through).
|
|
176
178
|
"""
|
|
177
179
|
clifford_ops_in_moment: list[ops.Operation] = [
|
|
178
180
|
op for op in moment.operations if _is_clifford_op(op)
|
|
179
181
|
]
|
|
180
|
-
|
|
181
|
-
# fixed.
|
|
182
|
-
affected_qubits = [q for op in clifford_ops_in_moment for q in op.qubits]
|
|
183
|
-
all_cliffords_in_gate: ops.CliffordGate = ops.CliffordGate.from_op_list(
|
|
184
|
-
clifford_ops_in_moment, affected_qubits
|
|
185
|
-
)
|
|
186
|
-
return input_pauli_ops.after(all_cliffords_in_gate.on(*affected_qubits))
|
|
182
|
+
return input_pauli_ops.after(clifford_ops_in_moment)
|
|
187
183
|
|
|
188
184
|
|
|
189
185
|
def _get_stop_qubits(moment: circuits.Moment) -> set[ops.Qid]:
|
|
@@ -197,7 +193,7 @@ def _get_stop_qubits(moment: circuits.Moment) -> set[ops.Qid]:
|
|
|
197
193
|
|
|
198
194
|
|
|
199
195
|
def _need_merge_pulled_through(op_at_q: ops.Operation, is_at_last_busy_moment: bool) -> bool:
|
|
200
|
-
"""With a pulling through
|
|
196
|
+
"""With a pulling through pauli gate before op_at_q, need to merge with the
|
|
201
197
|
pauli in the conditions below."""
|
|
202
198
|
# The op must be mergable and single-qubit
|
|
203
199
|
if not (_is_single_qubit_operation(op_at_q) and has_unitary(op_at_q)):
|
|
@@ -234,7 +230,7 @@ def add_dynamical_decoupling(
|
|
|
234
230
|
|
|
235
231
|
busy_moment_range_by_qubit = _calc_busy_moment_range_of_each_qubit(orig_circuit)
|
|
236
232
|
|
|
237
|
-
# Stores all the moments of the output circuit
|
|
233
|
+
# Stores all the moments of the output circuit chronologically.
|
|
238
234
|
transformed_moments: list[circuits.Moment] = []
|
|
239
235
|
# A PauliString stores the result of 'pulling' Pauli gates past each operations
|
|
240
236
|
# right before the current moment.
|
|
@@ -247,7 +243,7 @@ def add_dynamical_decoupling(
|
|
|
247
243
|
pulled_through *= pauli_map[insert_gate].on(q)
|
|
248
244
|
return insert_gate.on(q)
|
|
249
245
|
|
|
250
|
-
# Insert and pull remaining
|
|
246
|
+
# Insert and pull remaining Pauli ops through the whole circuit.
|
|
251
247
|
# General ideas are
|
|
252
248
|
# * Pull through Clifford gates.
|
|
253
249
|
# * Stop at multi-qubit non-Clifford ops (and other non-mergable ops).
|
{cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cirq-core
|
|
3
|
-
Version: 1.5.0.
|
|
3
|
+
Version: 1.5.0.dev20250228014434
|
|
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
|
{cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/RECORD
RENAMED
|
@@ -4,8 +4,8 @@ cirq/_compat_test.py,sha256=Qq3ZcfgD-Nb81cEppQdJqhAyrVqXKtfXZYGXT0p-Wh0,34718
|
|
|
4
4
|
cirq/_doc.py,sha256=yDyWUD_2JDS0gShfGRb-rdqRt9-WeL7DhkqX7np0Nko,2879
|
|
5
5
|
cirq/_import.py,sha256=p9gMHJscbtDDkfHOaulvd3Aer0pwUF5AXpL89XR8dNw,8402
|
|
6
6
|
cirq/_import_test.py,sha256=6K_v0riZJXOXUphHNkGA8MY-JcmGlezFaGmvrNhm3OQ,1015
|
|
7
|
-
cirq/_version.py,sha256=
|
|
8
|
-
cirq/_version_test.py,sha256=
|
|
7
|
+
cirq/_version.py,sha256=st5pfHdcuFvWhnPbf7jkrC0lPMUEM-8BDK1c2sNs2y4,1206
|
|
8
|
+
cirq/_version_test.py,sha256=ECrpkOwO6IZplxoqJ3om2pdTZYD314hbVJCoRCiTZwU,147
|
|
9
9
|
cirq/conftest.py,sha256=X7yLFL8GLhg2CjPw0hp5e_dGASfvHx1-QT03aUbhKJw,1168
|
|
10
10
|
cirq/json_resolver_cache.py,sha256=p-vEOa-8GQ2cFIAdze-kd6C1un1uRvtujVPljVKaHBg,13557
|
|
11
11
|
cirq/py.typed,sha256=VFSlmh_lNwnaXzwY-ZuW-C2Ws5PkuDoVgBdNCs0jXJE,63
|
|
@@ -271,7 +271,7 @@ cirq/ops/boolean_hamiltonian.py,sha256=li003lNq6zS8pNPTobqzfzYJvyvaIpCVo3wkliI6H
|
|
|
271
271
|
cirq/ops/boolean_hamiltonian_test.py,sha256=1ey5yfYZPKZDsfM3jpCPAOpbPs_y8i4K_WvDK2d5_4Y,8518
|
|
272
272
|
cirq/ops/classically_controlled_operation.py,sha256=M4NAcChYcz-a88oyIwOnV4uP06S18Cbef4VnhMmjyrA,10374
|
|
273
273
|
cirq/ops/classically_controlled_operation_test.py,sha256=nIYyXfNH4E2IibZSLk6QDVHpfJQbuI_iWwirCH8rhi8,50209
|
|
274
|
-
cirq/ops/clifford_gate.py,sha256=
|
|
274
|
+
cirq/ops/clifford_gate.py,sha256=W3fDY04QlubdCLawmq-86WAcgYQxk0ugamVro8ABFDk,39899
|
|
275
275
|
cirq/ops/clifford_gate_test.py,sha256=MQzZRURV--SPjRGLk_ESMBz75YXtKwtQGg2jufFDR0w,40341
|
|
276
276
|
cirq/ops/common_channels.py,sha256=go4yhaRw0XNAr3TUBJ59SOhn2SKxf6bHmmrOHPbBYCY,37259
|
|
277
277
|
cirq/ops/common_channels_test.py,sha256=nQsSSxu7vtedb3ZUuw4hNKIX7MYI4x8lxvLyWMZNt10,30079
|
|
@@ -333,12 +333,12 @@ cirq/ops/pauli_interaction_gate.py,sha256=Ep7XwZMVP81Qq1J2MTc3kJ79h26daOZcLPxqN3
|
|
|
333
333
|
cirq/ops/pauli_interaction_gate_test.py,sha256=U9ORW5Ayx5PESPFiGESzWY-02qHklYcM1mYW56RWe_A,4544
|
|
334
334
|
cirq/ops/pauli_measurement_gate.py,sha256=AS9tzLGAOhJzRzVsW9m-WPz5Wx0sMS1jzhppn5qtW84,7239
|
|
335
335
|
cirq/ops/pauli_measurement_gate_test.py,sha256=uh3J0Ps3V3578V8qkRiEgIl6jBiv8DsXlk_vzLvOEhQ,6720
|
|
336
|
-
cirq/ops/pauli_string.py,sha256=
|
|
336
|
+
cirq/ops/pauli_string.py,sha256=sGs0TZt1mtGUarDphJkTkNvKppdV1mB67eSJkKwQiug,70032
|
|
337
337
|
cirq/ops/pauli_string_phasor.py,sha256=M5AGwwMueY-y7bl50KJHiYql7PF4AcsdBBZhsxkhCWE,17519
|
|
338
338
|
cirq/ops/pauli_string_phasor_test.py,sha256=91YXIm9RbqrG8dPdA18E9i4G7JT1epGvM4BZu6_YVzw,27796
|
|
339
339
|
cirq/ops/pauli_string_raw_types.py,sha256=6CgdPWYmOziP4uZbrIsRW0sDSMmV1GioGdAk0owFITU,2240
|
|
340
340
|
cirq/ops/pauli_string_raw_types_test.py,sha256=SZPluslZPGffPq93F5apESBygWZ2cj7BEX6dQuawRQE,2648
|
|
341
|
-
cirq/ops/pauli_string_test.py,sha256=
|
|
341
|
+
cirq/ops/pauli_string_test.py,sha256=sE2Kje6qmHJzhdVja3fa3Er8g3XJ8l_8hzjgioSFIn4,75742
|
|
342
342
|
cirq/ops/pauli_sum_exponential.py,sha256=_9JERthST1PRwunplPQKIaJaOL45Kbl1oJ5CYUJWlTU,4876
|
|
343
343
|
cirq/ops/pauli_sum_exponential_test.py,sha256=wVnJ3FSpEimHT8ERVkmljALrgSuuDYo6GRg91uJ7ztk,5370
|
|
344
344
|
cirq/ops/permutation_gate.py,sha256=2h8n76N2M3nu5MA8JkRQgVLByq5cOEluKUN042ClSRs,4196
|
|
@@ -364,7 +364,7 @@ cirq/ops/raw_types.py,sha256=pBnjIMgnX5426rzC6KQuUSbI3VL1iLAjpFrsqSygjtY,42092
|
|
|
364
364
|
cirq/ops/raw_types_test.py,sha256=U2sAzc6DjpOmgHafGv94VJXqZHm7J898khmJoHAawHQ,33940
|
|
365
365
|
cirq/ops/state_preparation_channel.py,sha256=PjVtoLbjBAy_XqnFAY40Am-NifeuCFVVLW6RJxph5sQ,4778
|
|
366
366
|
cirq/ops/state_preparation_channel_test.py,sha256=yKUvLw_ft6cvIgRJcFQ779wZS-V6V-pzQq-rZRWdCmU,5922
|
|
367
|
-
cirq/ops/swap_gates.py,sha256=
|
|
367
|
+
cirq/ops/swap_gates.py,sha256=Rf3zF_dM6NM9LGvYqRr6QiX0qOxLBhp7yaFs-Awjog8,11792
|
|
368
368
|
cirq/ops/swap_gates_test.py,sha256=_CihLf6rY4PNphCkH-S5mLJQYZW9ILjnnwUyQ9b0Blg,7452
|
|
369
369
|
cirq/ops/tags.py,sha256=B3nEsZQTurGPJodH7aDoreNSatqawTxwsmw8fSKaIlc,2294
|
|
370
370
|
cirq/ops/tags_test.py,sha256=4V9twOuCXd7Glvj9p3RW-tZ4-bfLtC1tmonR4soKNA0,1158
|
|
@@ -1045,7 +1045,7 @@ cirq/transformers/drop_empty_moments.py,sha256=Rtn_BrpwkLXyZBdLzwdnsnEGWTdYuf1xO
|
|
|
1045
1045
|
cirq/transformers/drop_empty_moments_test.py,sha256=G8pZmTfi8NG2NpGz_K3LZu5NQoqa-xPMCuZjwEu07xk,1907
|
|
1046
1046
|
cirq/transformers/drop_negligible_operations.py,sha256=8eyOMy7bra2wJAjORbk6QjwHiLdL5SfwRaz8D2Dazbw,2083
|
|
1047
1047
|
cirq/transformers/drop_negligible_operations_test.py,sha256=gqL6RoDPm6Zf4RxtprBenFyIsZQPUxmPur9oRl0Yr3U,3823
|
|
1048
|
-
cirq/transformers/dynamical_decoupling.py,sha256=
|
|
1048
|
+
cirq/transformers/dynamical_decoupling.py,sha256=w3Gv9_dFMl2u6h0oKWWYTUuYXDFTqgBlP5HT3NpSyCc,14700
|
|
1049
1049
|
cirq/transformers/dynamical_decoupling_test.py,sha256=XCLH9Clco1KM6NXQmaVYCpUR1SALBRofgFgCH79RBuI,44690
|
|
1050
1050
|
cirq/transformers/eject_phased_paulis.py,sha256=usuPCxHgZf6Aw6pqIU4vOvaOypH4SiT2lY8VwAnlObs,13975
|
|
1051
1051
|
cirq/transformers/eject_phased_paulis_test.py,sha256=-mXsfbi3V0ojC_YqoQM5otzdW4kjGusCx6F-kCv8M98,15834
|
|
@@ -1202,8 +1202,8 @@ cirq/work/sampler.py,sha256=bE5tmVkcR6cZZMLETxDfHehdsYUMbx2RvBeIBetehI4,19187
|
|
|
1202
1202
|
cirq/work/sampler_test.py,sha256=hL2UWx3dz2ukZVNxWftiKVvJcQoLplLZdQm-k1QcA40,13282
|
|
1203
1203
|
cirq/work/zeros_sampler.py,sha256=x1C7cup66a43n-3tm8QjhiqJa07qcJW10FxNp9jJ59Q,2356
|
|
1204
1204
|
cirq/work/zeros_sampler_test.py,sha256=JIkpBBFPJe5Ba4142vzogyWyboG1Q1ZAm0UVGgOoZn8,3279
|
|
1205
|
-
cirq_core-1.5.0.
|
|
1206
|
-
cirq_core-1.5.0.
|
|
1207
|
-
cirq_core-1.5.0.
|
|
1208
|
-
cirq_core-1.5.0.
|
|
1209
|
-
cirq_core-1.5.0.
|
|
1205
|
+
cirq_core-1.5.0.dev20250228014434.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
1206
|
+
cirq_core-1.5.0.dev20250228014434.dist-info/METADATA,sha256=rrCHAML9zdH0J9WXYJcziz7dhREyHw4v279vCCIUk2Q,4817
|
|
1207
|
+
cirq_core-1.5.0.dev20250228014434.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
1208
|
+
cirq_core-1.5.0.dev20250228014434.dist-info/top_level.txt,sha256=Sz9iOxHU0IEMLSFGwiwOCaN2e9K-jFbBbtpPN1hB73g,5
|
|
1209
|
+
cirq_core-1.5.0.dev20250228014434.dist-info/RECORD,,
|
{cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/LICENSE
RENAMED
|
File without changes
|
{cirq_core-1.5.0.dev20250226233318.dist-info → cirq_core-1.5.0.dev20250228014434.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|