22
22
23
23
import numpy as np
24
24
25
- from cirq import circuits , ops , protocols
25
+ from cirq import ops , protocols
26
+ from cirq .circuits import Circuit , FrozenCircuit , Moment
26
27
from cirq .protocols import unitary_protocol
27
28
from cirq .protocols .has_stabilizer_effect_protocol import has_stabilizer_effect
28
29
from cirq .protocols .has_unitary_protocol import has_unitary
@@ -113,17 +114,15 @@ def _is_single_qubit_operation(operation: ops.Operation) -> bool:
113
114
return len (operation .qubits ) == 1
114
115
115
116
116
- def _is_single_qubit_gate_moment (moment : circuits . Moment ) -> bool :
117
+ def _is_single_qubit_gate_moment (moment : Moment ) -> bool :
117
118
return all (_is_single_qubit_operation (op ) for op in moment )
118
119
119
120
120
121
def _is_clifford_op (op : ops .Operation ) -> bool :
121
122
return has_unitary (op ) and has_stabilizer_effect (op )
122
123
123
124
124
- def _calc_busy_moment_range_of_each_qubit (
125
- circuit : circuits .FrozenCircuit ,
126
- ) -> dict [ops .Qid , list [int ]]:
125
+ def _calc_busy_moment_range_of_each_qubit (circuit : FrozenCircuit ) -> dict [ops .Qid , list [int ]]:
127
126
busy_moment_range_by_qubit : dict [ops .Qid , list [int ]] = {
128
127
q : [len (circuit ), - 1 ] for q in circuit .all_qubits ()
129
128
}
@@ -134,7 +133,7 @@ def _calc_busy_moment_range_of_each_qubit(
134
133
return busy_moment_range_by_qubit
135
134
136
135
137
- def _is_insertable_moment (moment : circuits . Moment , single_qubit_gate_moments_only : bool ) -> bool :
136
+ def _is_insertable_moment (moment : Moment , single_qubit_gate_moments_only : bool ) -> bool :
138
137
return not single_qubit_gate_moments_only or _is_single_qubit_gate_moment (moment )
139
138
140
139
@@ -150,9 +149,7 @@ def _merge_single_qubit_ops_to_phxz(
150
149
return gate .on (q )
151
150
152
151
153
- def _try_merge_single_qubit_ops_of_two_moments (
154
- m1 : circuits .Moment , m2 : circuits .Moment
155
- ) -> tuple [circuits .Moment , ...]:
152
+ def _try_merge_single_qubit_ops_of_two_moments (m1 : Moment , m2 : Moment ) -> tuple [Moment , ...]:
156
153
"""Merge single qubit ops of 2 moments if possible, returns 2 moments otherwise."""
157
154
for q in m1 .qubits & m2 .qubits :
158
155
op1 = m1 .operation_at (q )
@@ -169,12 +166,10 @@ def _try_merge_single_qubit_ops_of_two_moments(
169
166
# ops_on_q may contain 1 op or 2 ops.
170
167
ops_on_q = [op for op in [m .operation_at (q ) for m in [m1 , m2 ]] if op is not None ]
171
168
merged_ops .add (_merge_single_qubit_ops_to_phxz (q , tuple (ops_on_q )))
172
- return (circuits . Moment (merged_ops ),)
169
+ return (Moment (merged_ops ),)
173
170
174
171
175
- def _calc_pulled_through (
176
- moment : circuits .Moment , input_pauli_ops : ops .PauliString
177
- ) -> ops .PauliString :
172
+ def _calc_pulled_through (moment : Moment , input_pauli_ops : ops .PauliString ) -> ops .PauliString :
178
173
"""Calculates the pulled_through such that circuit(input_pauli_ops, moment.clifford_ops) is
179
174
equivalent to circuit(moment.clifford_ops, pulled_through).
180
175
"""
@@ -184,7 +179,7 @@ def _calc_pulled_through(
184
179
return input_pauli_ops .after (clifford_ops_in_moment )
185
180
186
181
187
- def _get_stop_qubits (moment : circuits . Moment ) -> set [ops .Qid ]:
182
+ def _get_stop_qubits (moment : Moment ) -> set [ops .Qid ]:
188
183
stop_pulling_through_qubits : set [ops .Qid ] = set ()
189
184
for op in moment :
190
185
if (not _is_clifford_op (op ) and not _is_single_qubit_operation (op )) or not has_unitary (
@@ -233,7 +228,7 @@ def add_dynamical_decoupling(
233
228
busy_moment_range_by_qubit = _calc_busy_moment_range_of_each_qubit (orig_circuit )
234
229
235
230
# Stores all the moments of the output circuit chronologically.
236
- transformed_moments : list [circuits . Moment ] = []
231
+ transformed_moments : list [Moment ] = []
237
232
# A PauliString stores the result of 'pulling' Pauli gates past each operations
238
233
# right before the current moment.
239
234
pulled_through : ops .PauliString = ops .PauliString ()
@@ -277,7 +272,7 @@ def _update_pulled_through(q: ops.Qid, insert_gate: ops.Gate) -> ops.Operation:
277
272
# Need to insert a new moment before current moment
278
273
if new_moment_ops :
279
274
moments_to_be_appended = _try_merge_single_qubit_ops_of_two_moments (
280
- transformed_moments [- 1 ], circuits . Moment (new_moment_ops )
275
+ transformed_moments [- 1 ], Moment (new_moment_ops )
281
276
)
282
277
if len (moments_to_be_appended ) == 1 :
283
278
transformed_moments .pop ()
@@ -291,7 +286,7 @@ def _update_pulled_through(q: ops.Qid, insert_gate: ops.Gate) -> ops.Operation:
291
286
):
292
287
new_moment_ops .append (_update_pulled_through (q , next (dd_iter_by_qubits [q ])))
293
288
moments_to_be_appended = _try_merge_single_qubit_ops_of_two_moments (
294
- transformed_moments .pop (), circuits . Moment (new_moment_ops )
289
+ transformed_moments .pop (), Moment (new_moment_ops )
295
290
)
296
291
transformed_moments .extend (moments_to_be_appended )
297
292
@@ -325,7 +320,7 @@ def _update_pulled_through(q: ops.Qid, insert_gate: ops.Gate) -> ops.Operation:
325
320
updated_moment_ops .add (updated_op )
326
321
327
322
if updated_moment_ops :
328
- updated_moment = circuits . Moment (updated_moment_ops )
323
+ updated_moment = Moment (updated_moment_ops )
329
324
transformed_moments .append (updated_moment )
330
325
331
326
# Step 3, update pulled through.
@@ -339,8 +334,8 @@ def _update_pulled_through(q: ops.Qid, insert_gate: ops.Gate) -> ops.Operation:
339
334
if ending_moment_ops :
340
335
transformed_moments .extend (
341
336
_try_merge_single_qubit_ops_of_two_moments (
342
- transformed_moments .pop (), circuits . Moment (ending_moment_ops )
337
+ transformed_moments .pop (), Moment (ending_moment_ops )
343
338
)
344
339
)
345
340
346
- return circuits . Circuit ( transformed_moments )
341
+ return Circuit . from_moments ( * transformed_moments )
0 commit comments