|
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