View source on GitHub |
Apply operations to pairs of qubits or modes using a swap network.
openfermion.circuits.swap_network(
qubits: Sequence[cirq.Qid],
operation: Callable[[int, int, cirq.Qid, cirq.Qid], cirq.OP_TREE] = (lambda p, q, p_qubit, q_qubit: ()),
fermionic: bool = False,
offset: bool = False
) -> List[cirq.Operation]
This is used for applying operations between arbitrary pairs of qubits or fermionic modes using only nearest-neighbor interactions on a linear array of qubits. It works by reversing the order of qubits or modes with a sequence of swap gates and applying an operation when the relevant qubits or modes become adjacent. For fermionic modes, this assumes the Jordan-Wigner Transform.
Examples
Input:
.. testcode::
import cirq
from openfermion import swap_network
qubits = cirq.LineQubit.range(4)
circuit = cirq.Circuit(swap_network(qubits))
print(circuit)
Output:
.. testoutput::
0: ───×───────×───────
│ │
1: ───×───×───×───×───
│ │
2: ───×───×───×───×───
│ │
3: ───×───────×───────
Input:
.. testcode::
circuit = cirq.Circuit(swap_network(qubits, offset=True))
print(circuit)
Output:
.. testoutput::
0: ───────×───────×───
│ │
1: ───×───×───×───×───
│ │
2: ───×───×───×───×───
│ │
3: ───────×───────×───
Input:
.. testcode::
circuit = cirq.Circuit(
swap_network(
qubits,
lambda p, q, a, b: cirq.ISWAP(a, b)**-1 if abs(p - q) == 1
else cirq.CZ(a, b),
fermionic=True))
print(circuit)
Output:
.. testoutput::
0: ───iSwap──────×ᶠ────────────@───×ᶠ───────────────────
│ │ │ │
1: ───iSwap^-1───×ᶠ───@───×ᶠ───@───×ᶠ───iSwap──────×ᶠ───
│ │ │ │
2: ───iSwap──────×ᶠ───@───×ᶠ───@───×ᶠ───iSwap^-1───×ᶠ───
│ │ │ │
3: ───iSwap^-1───×ᶠ────────────@───×ᶠ───────────────────