|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
15 | | -from typing import Any, Dict, Iterable, Sequence, Tuple, TYPE_CHECKING |
| 15 | +from typing import Any, Dict, Sequence, Tuple, TYPE_CHECKING |
16 | 16 |
|
17 | 17 | from cirq import protocols, value |
18 | 18 | from cirq.ops import raw_types, swap_gates |
@@ -74,23 +74,21 @@ def _has_unitary_(self): |
74 | 74 | return True |
75 | 75 |
|
76 | 76 | 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]) |
94 | 92 |
|
95 | 93 | def _apply_unitary_(self, args: 'cirq.ApplyUnitaryArgs'): |
96 | 94 | # Compute the permutation index list. |
|
0 commit comments