Skip to content

Commit ee2b78f

Browse files
Optimise QubitPermutationGate decomposition (#6588)
1 parent 9ddb8c8 commit ee2b78f

File tree

1 file changed

+16
-18
lines changed

1 file changed

+16
-18
lines changed

cirq-core/cirq/ops/permutation_gate.py

+16-18
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import Any, Dict, Iterable, Sequence, Tuple, TYPE_CHECKING
15+
from typing import Any, Dict, Sequence, Tuple, TYPE_CHECKING
1616

1717
from cirq import protocols, value
1818
from cirq.ops import raw_types, swap_gates
@@ -74,23 +74,21 @@ def _has_unitary_(self):
7474
return True
7575

7676
def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
77-
n = len(qubits)
78-
qubit_ids = [*range(n)]
79-
is_sorted = False
80-
81-
def _swap_if_out_of_order(idx: int) -> Iterable['cirq.Operation']:
82-
nonlocal is_sorted
83-
if self._permutation[qubit_ids[idx]] > self._permutation[qubit_ids[idx + 1]]:
84-
yield swap_gates.SWAP(qubits[idx], qubits[idx + 1])
85-
qubit_ids[idx + 1], qubit_ids[idx] = qubit_ids[idx], qubit_ids[idx + 1]
86-
is_sorted = False
87-
88-
while not is_sorted:
89-
is_sorted = True
90-
for i in range(0, n - 1, 2):
91-
yield from _swap_if_out_of_order(i)
92-
for i in range(1, n - 1, 2):
93-
yield from _swap_if_out_of_order(i)
77+
permutation = [p for p in self.permutation]
78+
79+
for i in range(len(permutation)):
80+
81+
if permutation[i] == -1:
82+
continue
83+
cycle = [i]
84+
while permutation[cycle[-1]] != i:
85+
cycle.append(permutation[cycle[-1]])
86+
87+
for j in cycle:
88+
permutation[j] = -1
89+
90+
for idx in cycle[1:]:
91+
yield swap_gates.SWAP(qubits[cycle[0]], qubits[idx])
9492

9593
def _apply_unitary_(self, args: 'cirq.ApplyUnitaryArgs'):
9694
# Compute the permutation index list.

0 commit comments

Comments
 (0)