Skip to content

Commit 56d9010

Browse files
committed
upload to sync
1 parent 74e1df0 commit 56d9010

File tree

3 files changed

+37
-19
lines changed

3 files changed

+37
-19
lines changed

cirq-core/cirq/ops/gate_operation_test.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ def on(self, *qubits):
322322
(cirq.ZZPowGate(global_shift=0.5), cirq.ZZ, True),
323323
(cirq.ZPowGate(global_shift=0.5) ** sympy.Symbol('e'), cirq.Z, False),
324324
(cirq.Z ** sympy.Symbol('e'), cirq.Z ** sympy.Symbol('f'), False),
325+
(
326+
cirq.PhasedXPowGate(phase_exponent=1.5, exponent=1.0),
327+
cirq.PhasedXPowGate(phase_exponent=0.5, exponent=1.0),
328+
True,
329+
),
330+
(cirq.XPowGate(exponent=2.0), cirq.I, True),
325331
],
326332
)
327333
def test_equal_up_to_global_phase_on_gates(gate1, gate2, eq_up_to_global_phase):

cirq-core/cirq/transformers/dynamical_decoupling.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,20 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
"""Transformer pass that adds dynamical decoupling moments to a circuit."""
15+
"""Transformer pass that adds dynamical decoupling operations to a circuit."""
1616

1717
import enum
1818
from functools import reduce
1919
from typing import Any, Dict, Optional, Tuple
2020

21+
from cirq.transformers import transformer_api, transformer_primitives
2122
import cirq
2223
from cirq import value
2324
import numpy as np
2425

26+
# DO NOT SUBMIT
27+
import logging
28+
2529

2630
@enum.unique
2731
class _DynamicalDecouplingSchema(enum.Enum):
@@ -41,25 +45,28 @@ def _generate_dd_sequence_from_schema(
4145
) -> list['cirq.Gate']:
4246
match schema:
4347
case _DynamicalDecouplingSchema.XX_PAIR:
44-
return _repeat_sequence([cirq.XPowGate(), cirq.XPowGate()], num_idle_moments)
48+
return _repeat_sequence([cirq.X, cirq.X], num_idle_moments)
4549
case _DynamicalDecouplingSchema.YY_PAIR:
46-
return _repeat_sequence([cirq.YPowGate(), cirq.YPowGate()], num_idle_moments)
50+
return _repeat_sequence([cirq.Y, cirq.Y], num_idle_moments)
4751

4852

4953
def _validate_dd_sequence(dd_sequence: list['cirq.Gate']) -> None:
5054
if len(dd_sequence) < 2:
5155
raise ValueError('Invalid dynamical decoupling sequence. Expect more than one gates.')
5256
matrices = [cirq.unitary(gate) for gate in dd_sequence]
5357
product = reduce(np.matmul, matrices)
54-
if not np.array_equal(product, np.eye(2)):
58+
product_gate = cirq.MatrixGate(product)
59+
60+
a = cirq.NamedQubit("a")
61+
if cirq.equal_up_to_global_phase(product_gate(a), cirq.I(a)):
5562
raise ValueError(
56-
"Invalid dynamical decoupling sequence, sequence product doesn't equal" ' identity.'
63+
"Invalid dynamical decoupling sequence. Sequence should equal to identity operation up to a global phase."
5764
)
5865

5966

6067
@value.value_equality
6168
class DynamicalDecouplingModel:
62-
"""Dynamical decoupling model that generates dynamical decoupling gate sequences."""
69+
"""Dynamical decoupling model that generates dynamical decoupling operation sequences."""
6370

6471
def __init__(
6572
self,
@@ -84,7 +91,6 @@ def generate_dd_sequence(self, num_idle_moments: int = 2) -> list['cirq.Gate']:
8491
return _generate_dd_sequence_from_schema(self.schema, num_idle_moments)
8592
if self.base_dd_sequence:
8693
return _repeat_sequence(self.base_dd_sequence, num_idle_moments)
87-
return []
8894

8995
@classmethod
9096
def from_schema(cls, schema: str):
@@ -117,18 +123,23 @@ def _value_equality_values_(self) -> Any:
117123
return self.schema, self.base_dd_sequence
118124

119125

126+
@transformer_api.transformer(add_deep_support=True)
120127
def add_dynamical_decoupling(
121-
circuit: 'cirq.AbstractCircuit', dd_model: DynamicalDecouplingModel
128+
circuit: 'cirq.AbstractCircuit',
129+
dd_model: DynamicalDecouplingModel,
130+
*,
131+
context: Optional['cirq.TransformerContext'] = None,
122132
) -> 'cirq.Circuit':
123133
"""Add dynamical decoupling gates in a given circuit.
124134
125135
Args:
126136
circuit: Input circuit to transform.
137+
context: `cirq.TransformerContext` storing common configurable options for transformers.
127138
dd_model: Dynamical decoupling model that defines the schema to generate
128139
dynamical decoupling sequences.
129140
130141
Return:
131-
A circuit with dynamical decoupling operations.
142+
A copy of the input circuit with dynamical decoupling operations.
132143
"""
133144
last_busy_moment_by_qubits: Dict['cirq.Qid', int] = {q: 0 for q in circuit.all_qubits()}
134145
insert_into: list[Tuple[int, 'cirq.OP_TREE']] = []
@@ -141,6 +152,7 @@ def add_dynamical_decoupling(
141152
insert_into.append((last_busy_moment_by_qubits[q] + idx + 1, gate.on(q)))
142153
last_busy_moment_by_qubits[q] = moment_id
143154

144-
circuit.batch_insert_into(insert_into)
155+
updated_circuit = circuit.unfreeze(copy=True)
156+
updated_circuit.batch_insert_into(insert_into)
145157

146-
return circuit
158+
return updated_circuit

cirq-core/cirq/transformers/dynamical_decoupling_test.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def test_insert_provided_schema():
5959
dd_model=DynamicalDecouplingModel.from_schema("XX_PAIR"),
6060
)
6161

62-
# Insert one XX_PAIR dynamical decoupling sequence in idle moments.
62+
# Insert one YY_PAIR dynamical decoupling sequence in idle moments.
6363
assert_dd(
6464
input_circuit=cirq.Circuit(
6565
cirq.Moment(cirq.H(a)),
@@ -99,23 +99,23 @@ def test_insert_by_customized_dd_sequence():
9999
cirq.Moment(cirq.CNOT(b, c), cirq.X(a)),
100100
cirq.Moment(cirq.measure_each(a, b, c)),
101101
),
102-
dd_model=DynamicalDecouplingModel.from_base_dd_sequence([cirq.XPowGate(), cirq.XPowGate()]),
102+
dd_model=DynamicalDecouplingModel.from_base_dd_sequence([cirq.X, cirq.X]),
103103
)
104104

105105

106106
def test_dd_model_constructor():
107107
# Succeed
108108
DynamicalDecouplingModel.from_schema("XX_PAIR")
109109
DynamicalDecouplingModel.from_schema("YY_PAIR")
110-
DynamicalDecouplingModel.from_base_dd_sequence(
111-
[cirq.XPowGate(), cirq.XPowGate(), cirq.YPowGate(), cirq.YPowGate()]
112-
)
110+
DynamicalDecouplingModel.from_base_dd_sequence([cirq.X, cirq.X, cirq.Y, cirq.Y])
113111
# Fail
114112
with pytest.raises(ValueError, match="Specify either schema or base_dd_sequence"):
115113
DynamicalDecouplingModel()
116114
with pytest.raises(ValueError, match="Invalid schema name."):
117115
DynamicalDecouplingModel.from_schema("unimplemented_schema")
118-
with pytest.raises(ValueError, match="Invalid dynamical decoupling sequence. Expect more than one gates."):
119-
DynamicalDecouplingModel.from_base_dd_sequence([cirq.XPowGate()])
116+
with pytest.raises(
117+
ValueError, match="Invalid dynamical decoupling sequence. Expect more than one gates."
118+
):
119+
DynamicalDecouplingModel.from_base_dd_sequence([cirq.X])
120120
with pytest.raises(ValueError, match="Invalid dynamical decoupling sequence"):
121-
DynamicalDecouplingModel.from_base_dd_sequence([cirq.XPowGate(), cirq.YPowGate()])
121+
DynamicalDecouplingModel.from_base_dd_sequence([cirq.X, cirq.H])

0 commit comments

Comments
 (0)