workbench_algorithms.subroutines.swap_up
Qubricks for swap network circuits.
SwapUp
Bases: Qubrick
Canonical SwapUp circuit that acts on arbitrary input states.
Assuming an already-loaded list of \(n\) items, each \(b\) bits long, this routine "swaps up" item with index \(x\) from the loaded items to the top position, i.e., to the top \(b\) qubits. The other items remain in positions \(1, ..., n - 1\), permuted in some order.
This follows the construction introduced in "Trading T gates for dirty qubits in state preparation and unitary synthesis" (arXiv:1812.00954).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
permutation_qbk
|
Qubrick
|
Qubrick to implement the bitonic permutations. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute SwapUp circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Input number state. |
required |
target_reg
|
Qubits
|
Register we apply the swap network to. |
required |
reg_size
|
int
|
Number of bits in each item in the target register. |
required |
ctrl
|
Optional[Qubits, int]
|
Qreg to control on. Defaults to 0. |
0
|
BinaryToUnaryUncomputation
Bases: Qubrick
Circuit which undoes a binary to unary conversion.
Suppose we have an index register which encodes some integer \(i\) between zero and \(N - 1\) in binary, but we wish to convert this to unary. One way to do this would be to allocate \(N - 1\) ancillae (starting in the zero state), perform a Pauli X on the topmost ancilla, and "swap it down" to the \(i^{\text{th}}\) position (i.e. perform the dagger of SwapUp). This gives us a unary encoding of \(i\) on the ancillae entangled with a binary encoding of \(i\) on the index reg.
If we are later tasked with uncomputing/disentangling the ancillary register from the index reg, we could simply use SwapUp to bring the ON bit back to the top ancilla qubit, and then turn it back OFF with a Pauli X again. In this situation, by construction, we are returning all the ancillae back to zero. In this situation, we needn't use the canonical SwapUp circuit from ... for the uncomputation; we can instead employ the use of measurement-based uncomputation, which instead uses right elbows and no non-Clifford gates. This method is discussed in Appendix C and depicted in Fig. 10 in arXiv:1902.02134 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
permutation_qbk
|
Qubrick
|
Qubrick to implement the bitonic permutations.. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute reversal of Binary to Unary conversion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Input number state. |
required |
target_reg
|
Qubits
|
Register we apply the swap network to. |
required |
reg_size
|
int
|
Number of bits in each output register. |
required |
ctrl
|
Optional[Qubits, int]
|
Qreg to control on. Defaults to 0. |
0
|
InjectOp
Bases: Qubrick
Inject operation, defined as SwapUp \(^\dagger\) Op SwapUp.
This follows the construction introduced in Eq. 9 in "Exponentially faster implementations of Select(H) for fermionic Hamiltonians" (arXiv:2004.04170).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
swap_up
|
Qubrick
|
SwapUp implementation. |
required |
op
|
Qubrick
|
The unitary to inject. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute Inject circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Input number state. |
required |
target_reg
|
Qubits or VectorRegister
|
Register to apply the operation to. |
required |
reg_size
|
int
|
Number of bits in each item in the target register. |
required |
ctrl
|
Optional[Qubits, int]
|
Qreg to control on. Defaults to 0. |
0
|
Note
For single-qubit unitaries (reg_size = 1), you can pass Qubits as target_reg.
For multi-qubit unitaries (reg_size > 1), use VectorRegister as target_reg.