Skip to content

Commit 3ae49b1

Browse files
committed
Apply comments of removing dynamical decoupling model class.
1 parent 427227d commit 3ae49b1

File tree

7 files changed

+104
-168
lines changed

7 files changed

+104
-168
lines changed

cirq-core/cirq/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,6 @@
337337
from cirq.transformers import (
338338
AbstractInitialMapper,
339339
add_dynamical_decoupling,
340-
DynamicalDecouplingModel,
341340
align_left,
342341
align_right,
343342
CompilationTargetGateset,

cirq-core/cirq/json_resolver_cache.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ def _symmetricalqidpair(qids):
102102
import sympy
103103

104104
return {
105-
'DynamicalDecouplingModel': cirq.DynamicalDecouplingModel,
106105
'AmplitudeDampingChannel': cirq.AmplitudeDampingChannel,
107106
'AnyIntegerPowerGateFamily': cirq.AnyIntegerPowerGateFamily,
108107
'AnyUnitaryGateFamily': cirq.AnyUnitaryGateFamily,

cirq-core/cirq/protocols/json_test_data/DynamicalDecouplingModel.json

Lines changed: 0 additions & 21 deletions
This file was deleted.

cirq-core/cirq/protocols/json_test_data/DynamicalDecouplingModel.repr

Lines changed: 0 additions & 2 deletions
This file was deleted.

cirq-core/cirq/transformers/__init__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,7 @@
7878

7979
from cirq.transformers.drop_negligible_operations import drop_negligible_operations
8080

81-
from cirq.transformers.dynamical_decoupling import (
82-
add_dynamical_decoupling,
83-
DynamicalDecouplingModel,
84-
)
81+
from cirq.transformers.dynamical_decoupling import add_dynamical_decoupling
8582

8683
from cirq.transformers.eject_z import eject_z
8784

cirq-core/cirq/transformers/dynamical_decoupling.py

Lines changed: 60 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -14,143 +14,105 @@
1414

1515
"""Transformer pass that adds dynamical decoupling operations to a circuit."""
1616

17-
import enum
1817
from functools import reduce
19-
from typing import Any, Dict, Optional, Tuple
18+
from typing import Dict, Optional, Sequence, Tuple, Union
2019

2120
from cirq.transformers import transformer_api
2221
import cirq
23-
from cirq import value
2422
import numpy as np
2523

2624

27-
@enum.unique
28-
class _DynamicalDecouplingSchema(enum.Enum):
29-
"""Supported schemes of dynamical decoupling."""
30-
31-
XX_PAIR = 'XX_PAIR'
32-
X_XINV = 'X_XINV'
33-
YY_PAIR = 'YY_PAIR'
34-
Y_YINV = 'Y_YINV'
35-
36-
37-
def _repeat_sequence(base_sequence: list['cirq.Gate'], num_idle_moments: int):
25+
def _repeat_sequence(
26+
base_sequence: Sequence['cirq.Gate'], num_idle_moments: int
27+
) -> Sequence['cirq.Gate']:
28+
"""Returns the longest possible dynamical decoupling sequence."""
3829
repeat_times = num_idle_moments // len(base_sequence)
39-
return base_sequence * repeat_times
30+
return list(base_sequence) * repeat_times
4031

4132

42-
def _generate_dd_sequence_from_schema(
43-
schema: _DynamicalDecouplingSchema, num_idle_moments: int = 2
44-
) -> list['cirq.Gate']:
33+
def _get_dd_sequence_from_schema_name(schema: str) -> Sequence['cirq.Gate']:
34+
"""Gets dynamical decoupling sequence from a schema name."""
35+
dd_sequence: Sequence['cirq.Gate']
4536
match schema:
46-
case _DynamicalDecouplingSchema.XX_PAIR:
47-
return _repeat_sequence([cirq.X, cirq.X], num_idle_moments)
48-
case _DynamicalDecouplingSchema.X_XINV:
49-
return _repeat_sequence([cirq.X, cirq.X**-1], num_idle_moments)
50-
case _DynamicalDecouplingSchema.YY_PAIR:
51-
return _repeat_sequence([cirq.Y, cirq.Y], num_idle_moments)
52-
case _DynamicalDecouplingSchema.Y_YINV:
53-
return _repeat_sequence([cirq.Y, cirq.Y**-1], num_idle_moments)
37+
case 'XX_PAIR':
38+
dd_sequence = (cirq.X, cirq.X)
39+
case 'X_XINV':
40+
dd_sequence = (cirq.X, cirq.X**-1)
41+
case 'YY_PAIR':
42+
dd_sequence = (cirq.Y, cirq.Y)
43+
case 'Y_YINV':
44+
dd_sequence = (cirq.Y, cirq.Y**-1)
45+
case _:
46+
raise ValueError('Invalid schema name.')
47+
return dd_sequence
48+
49+
50+
def _validate_dd_sequence(dd_sequence: Sequence['cirq.Gate']) -> Tuple[bool, Optional[str]]:
51+
"""Validates a given dynamical decoupling sequence.
5452
53+
Args:
54+
dd_sequence: Input dynamical sequence to be validated.
5555
56-
def _validate_dd_sequence(dd_sequence: list['cirq.Gate']) -> None:
56+
Returns:
57+
A tuple containing:
58+
- is_valid (bool): True if the dd sequence is valid, False otherwise.
59+
- error_message (str): An error message if the dd sequence is invalid, else None.
60+
"""
5761
if len(dd_sequence) < 2:
58-
raise ValueError('Invalid dynamical decoupling sequence. Expect more than one gates.')
62+
return False, 'Invalid dynamical decoupling sequence. Expect more than one gates.'
5963
matrices = [cirq.unitary(gate) for gate in dd_sequence]
6064
product = reduce(np.matmul, matrices)
6165

6266
if not cirq.equal_up_to_global_phase(product, np.eye(2)):
63-
raise ValueError(
64-
"Invalid dynamical decoupling sequence. Expect sequence production equals identity"
65-
f" up to a global phase, got {product}.".replace('\n', ' ')
67+
return False, (
68+
'Invalid dynamical decoupling sequence. Expect sequence production equals'
69+
f' identity up to a global phase, got {product}.'.replace('\n', ' ')
6670
)
67-
68-
69-
@value.value_equality
70-
class DynamicalDecouplingModel:
71-
"""Dynamical decoupling model that generates dynamical decoupling operation sequences."""
72-
73-
def __init__(
74-
self,
75-
schema: Optional[_DynamicalDecouplingSchema] = None,
76-
base_dd_sequence: Optional[list['cirq.Gate']] = None,
77-
):
78-
if not schema and not base_dd_sequence:
79-
raise ValueError(
80-
'Specify either schema or base_dd_sequence to construct a valid'
81-
' DynamicalDecouplingModel.'
82-
)
83-
self.schema = schema
84-
self.base_dd_sequence = base_dd_sequence
85-
if base_dd_sequence:
86-
_validate_dd_sequence(base_dd_sequence)
87-
88-
def generate_dd_sequence(self, num_idle_moments: int = 2) -> list['cirq.Gate']:
89-
"""Returns the longest possible dynamical decoupling sequence."""
90-
if num_idle_moments <= 0:
91-
return []
92-
if self.schema:
93-
dd_sequence = _generate_dd_sequence_from_schema(self.schema, num_idle_moments)
94-
elif self.base_dd_sequence:
95-
dd_sequence = _repeat_sequence(self.base_dd_sequence, num_idle_moments)
96-
return dd_sequence
97-
98-
@classmethod
99-
def from_schema(cls, schema: str):
100-
"""Create dynamical decoupling model according to a given schema."""
101-
if not schema in _DynamicalDecouplingSchema.__members__:
102-
raise ValueError("Invalid schema name.")
103-
return cls(schema=_DynamicalDecouplingSchema[schema])
104-
105-
@classmethod
106-
def from_base_dd_sequence(cls, base_dd_sequence: list['cirq.Gate']):
107-
"""Create dynamical decoupling model according to a base sequence."""
108-
return cls(base_dd_sequence=base_dd_sequence)
109-
110-
def _json_dict_(self) -> Dict[str, Any]:
111-
d: Dict[str, Any] = {}
112-
if self.schema:
113-
d['schema'] = self.schema.name
114-
if self.base_dd_sequence:
115-
d['base_dd_sequence'] = self.base_dd_sequence
116-
return d
117-
118-
@classmethod
119-
def _from_json_dict_(cls, schema=None, base_dd_sequence=None, **kwargs):
120-
if schema:
121-
return cls(schema=_DynamicalDecouplingSchema[schema])
122-
if base_dd_sequence:
123-
return cls(base_dd_sequence=base_dd_sequence)
124-
125-
def _value_equality_values_(self) -> Any:
126-
return self.schema, self.base_dd_sequence
71+
return True, None
12772

12873

12974
@transformer_api.transformer
13075
def add_dynamical_decoupling(
13176
circuit: 'cirq.AbstractCircuit',
13277
*,
13378
context: Optional['cirq.TransformerContext'] = None,
134-
dd_model: DynamicalDecouplingModel = DynamicalDecouplingModel.from_schema("X_XINV"),
79+
schema: Union[str, Sequence['cirq.Gate']] = 'X_XINV',
13580
) -> 'cirq.Circuit':
136-
"""Add dynamical decoupling gate operations to a given circuit.
81+
"""Adds dynamical decoupling gate operations to idle moments of a given circuit.
82+
This transformer preserves the moment structure of the circuit.
13783
13884
Args:
13985
circuit: Input circuit to transform.
14086
context: `cirq.TransformerContext` storing common configurable options for transformers.
141-
dd_model: Dynamical decoupling model that defines the schema to generate dynamical
142-
decoupling sequences.
87+
schema: Dynamical decoupling schema name or a dynamical decoupling sequence.
88+
If a schema is specified, provided dynamical decouping sequence will be used.
89+
Otherwise, customized dynamical decoupling sequence will be applied.
14390
144-
Return:
91+
Returns:
14592
A copy of the input circuit with dynamical decoupling operations.
93+
94+
Raises:
95+
ValueError: If schema is not valid.
14696
"""
14797
last_busy_moment_by_qubits: Dict['cirq.Qid', int] = {q: 0 for q in circuit.all_qubits()}
14898
insert_into: list[Tuple[int, 'cirq.OP_TREE']] = []
14999

100+
if isinstance(schema, str):
101+
try:
102+
base_dd_sequence = _get_dd_sequence_from_schema_name(schema)
103+
except ValueError:
104+
raise
105+
else:
106+
is_valid, error_message = _validate_dd_sequence(schema)
107+
if is_valid:
108+
base_dd_sequence = schema
109+
else:
110+
raise ValueError(error_message)
111+
150112
for moment_id, moment in enumerate(circuit):
151113
for q in moment.qubits:
152-
insert_gates = dd_model.generate_dd_sequence(
153-
num_idle_moments=moment_id - last_busy_moment_by_qubits[q] - 1
114+
insert_gates = _repeat_sequence(
115+
base_dd_sequence, num_idle_moments=moment_id - last_busy_moment_by_qubits[q] - 1
154116
)
155117
for idx, gate in enumerate(insert_gates):
156118
insert_into.append((last_busy_moment_by_qubits[q] + idx + 1, gate.on(q)))

0 commit comments

Comments
 (0)