workbench_algorithms.subroutines
Submodule for defining subroutines.
AliasSampling
Bases: Qubrick
Qubrick for implementing alias sampling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qrom
|
Qubrick
|
Data lookup instance. |
required |
usp
|
Qubrick
|
Uniform state preparation instance. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute_num_states
staticmethod
Helper to compute number of states to prepare in alias sampling (works for symbolics & numerics).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_list
|
list or SymbolicArray
|
List of coefficients to prepare. |
required |
Returns:
| Type | Description |
|---|---|
tuple
|
Number of states to prepare, and value to pad combined list by. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the inputs are not the correct type for either numerics or symbolics. |
compute
State preparation by alias sampling.
Note
Uses the circuit in Fig. 11 of arXiv:1805.03662 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prep_reg
|
Qubits or SymbolicQubits
|
Register to prepare coefficients onto. |
required |
input_list
|
list or SymbolicArray
|
List of coefficients to prepare. |
required |
bit_precision
|
int or Parameter
|
Number of bits to represent each coefficient. |
required |
lambda_val
|
int or Parameter
|
Power-of-two knob to trade off between gates
and qubits. If |
None
|
ctrl
|
Qubits, SymbolicQubits, or int
|
Control register. Defaults to no control, i.e. |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
AmpAmp
AmpAmp(
init_refl: Qubrick,
good_refl: Qubrick,
fixed_point: bool = False,
eps: float = 0.001,
use_radians: bool = False,
**kwargs,
)
Bases: Qubrick
Performs amplitude amplification to boost the amplitude of a desired outcome.
Amplitude amplification takes two reflections: a "good" reflection about a target state \(|\psi_{\text{good}}\rangle\) and a "starting" reflection about the state \(|\psi_{0}\rangle\) that forms the starting point of the routine. If the starting state \(|\psi_0\rangle\) is prepared with some (potentially low) overlap with the target state \(|\psi_{\text{good}}\rangle\), repeatedly applying these two reflections \(\mathcal{O}(1/\sqrt{p})\) times should result in a final state which has \(\Omega(1)\) overlap with the target state.
These reflections can't be made blindly: if you pick a number of iterations that is too small, you "undercook" the
state, and if you pick a number that is too high, you "overcook" the state, leading to low fidelities in both cases.
The optimal number of iterations depends on the initial success probability p_succ, which you may or may not know
a priori. AmpAmp requires p_succ to be passed as an argument in order to calculate the number of rounds needed and provides
provision for two scenarios:
- If you know
p_succexactly a priori, you can realize the good state deterministically following the procedure in "Quantum Amplitude Amplification and Estimation" (arXiv:quant-ph/0005055). - If you don't know
p_succ, we can use fixed point amplitude amplification (the Workbench Algorithms implementation follows "Fixed-point quantum search with an optimal number of queries" (arXiv:1409.3305) along with a lower bound on the success probability asp_succ. Unlike vanilla AA, fixed point AA is guaranteed to succeed for any number of iterations greater than some threshold (calculated from the lower bound on the success probability). Thus, while it may use more resources than necessary, it is useful for when we can't determinep_succexactly.
Note
The reflections that are passed to this Qubrick are entirely general - they may have additional parameters
that need to be passed to them. These parameters can be passed through the kwargs as if the AmpAmp
Qubrick has those parameters. For example, if you have a block encoding unitary which takes be_ancilla_reg as
an argument, you can do
AmpAmp(init_refl, good_refl).compute(sys_reg, p_succ, be_ancilla_reg=be_ancilla_reg).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
init_refl
|
Qubrick
|
Reflection about the initial state. |
required |
good_refl
|
Qubrick
|
Reflection about the good (target) state. |
required |
fixed_point
|
bool
|
Whether to use fixed point amplitude amplification rather than vanilla amplitude amplification.
Defaults to |
False
|
eps
|
float
|
Desired error \(\epsilon\) such that \(|\langle\psi_{f}|\psi_{targ}\rangle|^2 \geq 1 - \epsilon\).
Needed to calculate the fixed point rotation angles; not necessary if you use vanilla amplitude amplification. Defaults to
|
0.001
|
use_radians
|
bool
|
(Deprecated) True if angles in Radians |
False
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the amplitude amplification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_reg
|
Qubits
|
Main register the computation is performed on. |
required |
p_succ
|
float
|
The initial probability of obtaining the "good" state. If |
required |
ctrl
|
int | Qubits
|
Register the amplitude amplification is controlled on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Optional arguments that may be passed on to the reflection qubricks. |
{}
|
Other Parameters:
| Name | Type | Description |
|---|---|---|
be_ancilla_reg |
Qubrick
|
Block encoding register. |
data |
PauliSum or List[int]
|
Data for |
AmplitudeAmplifiedQubrick
AmplitudeAmplifiedQubrick(
base_qubrick: Qubrick,
init_refl: Qubrick,
good_refl: Qubrick,
fixed_point: bool = False,
eps: float = 0.001,
use_radians: bool = False,
**kwargs,
)
Bases: Qubrick
Performs amplitude amplification on the input Qubrick to provide an "amplified" Qubrick.
This Qubrick is intended to be used as a wrapper around a base Qubrick along with Amplitude Amplification (the AmpAmp Qubrick) in order to produce an amplitude amplified version of the base Qubrick.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_qubrick
|
Qubrick
|
The base qubrick to be amplified. |
required |
init_refl
|
Qubrick
|
Reflection about the initial state. |
required |
good_refl
|
Qubrick
|
Reflection about the good (target) state. |
required |
fixed_point
|
bool
|
Whether to use fixed point amplitude amplification rather than vanilla amplitude amplification.
Defaults to |
False
|
eps
|
float
|
Desired error \(\epsilon\) such that \(|\langle\psi_{f}|\psi_{targ}\rangle|^2 \geq 1 - \epsilon\).
Needed to calculate the fixed point rotation angles, not necessary for vanilla amp amp. Defaults to
|
0.001
|
use_radians
|
bool
|
(Deprecated) True if angles in Radians |
False
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the base qubrick along with amplitude amplification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_reg
|
Qubits
|
Main register the computation is performed on. |
required |
p_succ
|
float
|
The initial probability of obtaining the "good" state. If |
required |
ctrl
|
int | Qubits
|
Register the amplitude amplification is controlled on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Optional arguments that may be passed on to the AmpAmp Qubrick, reflection Qubricks, or the base Qubrick. |
{}
|
Other Parameters:
| Name | Type | Description |
|---|---|---|
be_ancilla_reg |
Qubrick
|
Block encoding register. |
data |
PauliSum or List[int]
|
Data for |
GoodReflectionBlockEncoding
Bases: Qubrick
Reflection about a block encoded good state (i.e., all block encoding auxiliary qubits in \(\ket{0}\)).
Implements the reflection
\((I - (1 - e^{i\phi})|0^m\rangle\langle 0^m|)\)
Note
See references "Quantum Amplitude Amplification and Estimation" (arXiv:quant-ph/0005055) and "Fixed-point quantum search with an optimal number of queries" (arXiv:1409.3305) for details.
compute
Compute the reflection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_reg
|
Qubits
|
Qubits register defining the system. Included to maintain compatibility with other Qubricks. |
required |
ancillae
|
Qubits
|
Auxiliary qubits used to block encode the matrix. |
required |
angle
|
float
|
Angle about which the generalized reflection is performed. |
180
|
ctrl
|
int | Qubits
|
Qubits to control the reflection on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments included to maintain compatibility with other reflections. |
{}
|
GoodReflectionGrover
Bases: Qubrick
Qubrick for reflecting about a good state in Grover.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
good_state
|
str
|
Binary representation of the good state as the basis state, e.g. '101' |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the reflection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_reg
|
Qubits
|
Register on which the state is prepared. |
required |
angle
|
float
|
Angle about which the generalized reflection is performed, in degrees. |
required |
ctrl
|
int | Qubits
|
Qubits to control the reflection on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments included to maintain compatibility with other reflections. |
{}
|
GroverDiffuser
Bases: Qubrick
Qubrick for Grover diffuser (reflection about the mean).
compute
Compute the reflection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_reg
|
Qubits
|
Register on which the state is prepared. |
required |
angle
|
float
|
Angle about which the generalized reflection is performed, in degrees. |
180
|
ctrl
|
int | Qubits
|
Qubits to control the reflection on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments included to maintain compatibility with other reflections. |
{}
|
InitReflectionBlockEncoding
Bases: Qubrick
Reflection about the initial state given a unitary that prepares that state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
unitary
|
Qubrick
|
Qubrick implementing the unitary to reflect about. |
required |
**kwargs
|
dict[str, Any]
|
Other key word arguments to pass to the Qubrick constructor. |
{}
|
compute
compute(
sys_reg: Qubits,
angle: float = 180,
ancillae: int | Qubits = 0,
ctrl: int | Qubits = 0,
**kwargs,
)
Compute the reflection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_reg
|
Qubits
|
Register on which the state is prepared. |
required |
angle
|
float
|
Angle about which the generalized reflection is performed, in degrees. |
180
|
ancillae
|
int | Qubits
|
Ancillae used to facillitate the implementation of the state. Defaults to 0. |
0
|
ctrl
|
int | Qubits
|
Qubits to control the reflection on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments included to maintain compatibility with other reflections. |
{}
|
InitReflectionFromUnitary
Bases: Qubrick
Reflection about the initial state given a unitary that prepares that state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
unitary
|
Qubrick
|
Qubrick implementing the unitary that prepares the state to reflect about. |
required |
**kwargs
|
dict[str, Any]
|
Other key word arguments to pass to the Qubrick constructor. |
{}
|
compute
Compute the reflection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_reg
|
Qubits
|
Register on which the state is prepared. |
required |
angle
|
float
|
Angle about which the generalized reflection is performed, in degrees. |
180
|
ctrl
|
int | Qubits
|
Qubits to control the reflection on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments included to maintain compatibility with other reflections. |
{}
|
Antisymmetrizer
Bases: Qubrick
Qubrick to antisymmetrize a register of qubits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prep_qbk
|
Qubrick
|
A state preparation Qubrick. |
required |
prob_knob
|
(Optional, int)
|
A value to use which determines the number of qubits to use per seed register, which influences the probability of needing to restart. Defaults to None, in which case, a default value which ensures >= 1/2 probability of success is used. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Circuit for preparation of an antisymmetrized state.
The antisymmetrization procedure works as follows:
- We prepare an auxiliary "seed" register in an equal superposition state.
- We employ a sorting network on the seed register, keeping a record of all permutations made during the sort on another "record" register.
- The seed register is measured in order to post-select on the collision-free subspace. If we observe a collision, we go back to step 1. If not, continue.
- We apply Pauli Zs on each record qubit.
- We use the record to reverse the sorting operations on the input system register, resulting in an equal superpotision of all permutations of the input state.
- Because we applied Pauli Zs on each record qubit prior to the sort reversal, we also phase each permutation state according to its parity.
The above prepares the desired antisymmetrized state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_reg
|
Qubits
|
Register to prepare antisymmetrized state on. |
required |
ctrl
|
(int, Qubits)
|
Control register for the routine. Defaults to 0. |
0
|
PowerOfTwoBatchedHammingWeightPhasing
PowerOfTwoBatchedHammingWeightPhasing(
hamming_weight_qubrick: Qubrick | None = None,
n_hwp_batches: int = 1,
rot_is_rz: bool = True,
use_black_box: bool = False,
**kwargs,
)
Bases: Qubrick
Implements Hamming weight phasing by splitting the target register into batches.
This Qubrick divides a large rotation tower into smaller batches, where the number of batches is a power of two. Each batch is processed with a smaller Hamming weight phasing circuit. This approach can significantly reduce the number of qubits and catalyst rotation requirements for large registers.
This is particularly useful for applications like Fermi-Hubbard simulation where the number of parallel Rz rotations is either L²/2 or L², where L is the lattice size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hamming_weight_qubrick
|
Qubrick | None
|
Qubrick for computing the Hamming weight for the Hamming weight phasing operation. If None, a default method using ComputeHammingWeightGroupOfThrees with GidneyAdd will be used. |
None
|
n_hwp_batches
|
int
|
Number of batches to split the rotations into. Must be a power of 2. Larger values reduce resource costs but may increase circuit depth. |
1
|
rot_is_rz
|
bool
|
Whether to use RZ rotations (True) or phase rotations (False). |
True
|
use_black_box
|
bool
|
Uses black box AV counts if set to True. Default is False. |
False
|
**kwargs
|
dict[str, Any]
|
Additional arguments to pass to the Qubrick constructor. |
{}
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If n_hwp_batches is not a power of 2. |
hamming_weight_qubrick
property
Returns the Hamming weight qubrick used for computation.
Returns:
| Type | Description |
|---|---|
Qubrick
|
The Hamming weight calculation Qubrick. |
compute
Computes the batched Hamming weight phasing operation.
This method splits the target register into batches, then applies a Hamming weight phasing operation to each batch separately. This approach can significantly reduce Toffoli gate counts and catalyst rotation requirements for large registers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rz_rotation_angle
|
float
|
Rotation angle (in degrees) for the phase operations. |
required |
target_register
|
Qubits
|
Register on which to apply the rotations. |
required |
ctrl
|
Qubits | int
|
Controls for the operation. Can be an integer bitmask or a Qubits register. Default is 0 (uncontrolled). |
0
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the number of batches is greater than the number of qubits in the target register. |
LCU
Bases: Qubrick
Implements a general block encoding using Linear Combination of Unitaries (LCU).
Constructs the block encoding as \(\text{PREP}-\text{SELECT}-\text{PREP}^\dagger\)
using provided Qubrick implementations of SELECT and PREP.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state_prep
|
StatePreparation
|
A Qubrick implementing a state preparation ( |
required |
select
|
Select
|
A Qubrick implementing a select ( |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
compute(
psi: Qubits,
be_ancilla_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
**kwargs: dict[str, Any],
)
Compute the block encoding.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
Target state register. |
required |
be_ancilla_reg
|
Qubits
|
Block encoding auxiliary register. |
required |
data
|
PauliSum | list[int]
|
Hamiltonian or bitstring values to be block-encoded. |
required |
ctrl
|
Qubits | int
|
Register to control on. Defaults to |
0
|
**kwargs
|
dict[str, Any]
|
Extra kwargs to maintain compatibility with other Qubricks. |
{}
|
CompressionGadget
Bases: Qubrick
Compression gadget for block-encoding powers.
Given BE[H_i], applies a BE[Prod H_i] according to https://arxiv.org/pdf/2208.06941 Fig. 3.
Note
The block-encoding is successful in the subspace where counter == 0. The controlled version is such that the controlled unitary is applied accordingly when the block-encoding's ancillae qubits are in the zero state. However, the controlled-qubrick might still have an action in other subspace. This allows to reduce the cost of the implementation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
strategy
|
CompressionGadgetStrategy
|
block-encoding of the hamiltonian H |
required |
adder
|
Qubrick
|
Adder qubrick |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
strategy
property
Set the strategy property so it can't be modified.
Returns:
| Type | Description |
|---|---|
CompressionGadgetStrategy
|
The Compression gadget strategy |
compute
Compute CompressionGadget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_reg
|
Qubits
|
System qubits to apply to block-encodings. |
required |
be_anc
|
int
|
Block-encoding ancilla register. |
required |
idx_stop
|
int
|
Final index of the multiplication. |
required |
idx_start
|
int
|
Starting index of the multiplication. |
0
|
counter
|
Qubits
|
Counter register to perform the compression, if None will be allocated at compute. |
None
|
ctrl
|
(Qubits, int)
|
Control register. |
0
|
CompressionGadgetStrategy
Bases: Protocol
Interface for applying block-encodings in compression gadget.
apply_compression_gadget_block_encoding
apply_compression_gadget_block_encoding(
system_reg: Qubits,
be_anc: Qubits,
idx: int,
ctrl: Qubits | int = 0,
)
Method describing how to apply the block encodings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system_reg
|
Qubits
|
System qubits. |
required |
be_anc
|
Qubits
|
Block-encoding's ancillary qubits. |
required |
idx
|
int
|
Iteration of the compression gadget. |
required |
ctrl
|
Qubits | int
|
Control register. |
0
|
DataLookupClean
DataLookupClean(
select: Select,
swap_up: SwapUpInterface,
fallback_read=FallbackCoinToss,
symbolic_mode: str = "worst",
**kwargs,
)
Bases: Qubrick
Data lookup (QROM) circuit using the SELECT-SwapUp architecture.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
select
|
Qubrick
|
SELECT unitary instance. |
required |
swap_up
|
Qubrick
|
SwapUp unitary instance. |
required |
fallback_read
|
FallbackReadGenerator
|
Constructor of an object providing results of read in case there's no state-vector simulator available. |
FallbackCoinToss
|
symbolic_mode
|
str
|
What kind of symbolic QREs should be provided. Can be either "worst" or "average". |
'worst'
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
compute(
index_reg: Qubits,
bits_of_precision: int,
data: Iterable[int],
lambda_val: int | None = None,
ctrl: Qubits | int = 0,
*,
clean: Qubits | None = None,
)
Compute data lookup (QROM) circuit with clean auxiliary qubits.
This routine loads data conditioned by an index register. It makes use of the SELECT-SwapUp constructions introduced in "Encoding Electronic Spectra in Quantum Circuits with Linear T Complexity" (arXiv:1805.03662), where we may tune a parameter (colloquially referred to as "lambda") that allows us to trade off between gates and qubits.
Depending on the input args and the chosen lambda value, we consider three cases:
-
If "lambda" is equal to 1, this means we do not introduce any additional auxiliary qubits. This case reduces the QROM to a classic SELECT.
-
If "lambda" is equal to the number of items we are loading, this case reduces to classically writing all data elements and using SwapUp to fetch a particular item and bring it to the top
b"clean" qubits. -
All other cases make use of both SELECT and SwapUp to coherently write and fetch indexed data, respectively.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Index register. |
required |
bits_of_precision
|
int
|
Number of bits to represent item in list. |
required |
data
|
Iterable[int]
|
List of data to load. |
required |
lambda_val
|
int | None
|
Power-of-two knob to trade off between gates
and qubits. If |
None
|
ctrl
|
Qubits | int
|
Qreg to control on. Defaults to 0. |
0
|
clean
|
Qubits | None
|
If passed in, will be used as the output qubits. Useful for reusing registers. |
None
|
Notes
With the introduction of a custom uncompute method for this class, the compute circuit is no longer fully coherent; if we are making use of additional junk registers, we measure them and record the read result to later be used during uncompute. This allows us to release auxiliary qubits that may otherwise constitute a significant space cost.
compute_phase_fixups
Use QROM data to compute the addresses that require phase fixups.
Returns:
| Type | Description |
|---|---|
list[int]
|
A list of each address (int) that requires a phase fixup. |
compute_phase_fixups_symbolic
Use QROM data to compute the addresses that require phase fixups.
It models the worst-case scenario, where all the addresses need a fixup, or the average scenario when only half of them do, depending on self.symbolic_mode.
Returns:
| Type | Description |
|---|---|
SymbolicArray
|
A list of each address (int) that requires a phase fixup. |
DataLookupDirtyNaive
Bases: Qubrick
Naive data lookup (QROM) oracle using dirty auxiliary qubits.
Introduced in Fig. 1D from "Trading T gates for dirty qubits in state preparation and unitary synthesis" (arXiv:1812.00954).
Note
This routine makes use of dirty, borrowable qubits. The auxiliary qubits in question can be
any qubits on the entirety of the QPU, so long as they are not the qubits acted on by
the routine itself. By "borrowable", we mean that after compute is called, the dirty
auxiliary qubits are returned to their initial state; we do not need to wait until uncomputation
for these qubits to be returned to their initial state.
The current implementation makes use of _dirty_qubits to find borrowable qubits; this will
likely change in the future once a dirty auxiliary qubits management scheme is formally implemented in Workbench.
A consequence of the current implementation is that when uncompute is called, the exact same dirty register
will be used. This is technically correct and permissible, but absolutely not necessary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
select
|
Qubrick
|
Select unitary instance. |
required |
swap_up
|
Qubrick
|
SwapUp unitary instance. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute data lookup (QROM) circuit with dirty auxiliary qubits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Index register. |
required |
b
|
int
|
Number of bits to represent item in list. |
required |
data
|
list
|
List of data to load. |
required |
lambda_val
|
int
|
Power-of-two knob to trade off between gates
and qubits. If |
None
|
ctrl
|
Optional[Qubits, int]
|
Qreg to control on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
DataLookupDirtyOptimized
Bases: Qubrick
Optimized data lookup (QROM) oracle using dirty auxiliary qubits.
Introduced in Fig. 4 from "Qubitization of Arbitrary Basis Quantum Chemistry Leveraging Sparsity and Low Rank Factorization" (arXiv:1902.02134).
Note
\(\text{SWAP}\) and \(\text{SWAP}^\dagger\) are switched in the code below from the drawing in Fig. 4 because \(\text{SWAP}\) and \(\text{SWAP}^\dagger\) in Workbench Algorithms are defined in the usual way as swapping the lth register up to the 0th, NOT the other way around.
This routine makes use of dirty, borrowable qubits. The auxiliary qubits in question can be
any qubits on the entirety of the QPU so long as they are not the qubits acted on by
the routine itself. By "borrowable", we mean that after compute is called, the dirty
auxiliary qubits are returned to their initial state; we do not need to wait until uncomputation
for these qubits to be returned to their initial state.
The current implementation makes use of _dirty_qubits to find borrowable qubits; this will
likely change in the future once a dirty auxiliary qubits management scheme is formally implemented in Workbench.
A consequence of the current implementation is that when uncompute is called, the exact same dirty register
will be used. This is technically correct and permissible, but absolutely not necessary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
select
|
Qubrick
|
Select unitary instance. |
required |
swap_up
|
Qubrick
|
SwapUp unitary instance. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute data lookup (QROM) circuit with dirty auxiliary qubits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Index register. |
required |
b
|
int
|
Number of bits to represent item in list. |
required |
data
|
list
|
List of data to load. |
required |
lambda_val
|
int
|
Power-of-two knob to trade off between gates
and qubits. If |
None
|
ctrl
|
Optional[Qubits, int]
|
Qreg to control on. Defaults to 0. |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
MultiplexedSparseDataLookup
Bases: Qubrick
Multiplexed data lookup oracle in Fig. (43) of arXiv:2007.14460.
The goal is to do a "multiplex of multiplexors", that is a quantum for loop over values \(k\) that index a second, inner for loop over \(k-\)dependent values \(j_k\), with the goal being to apply a series of bitstrings \(x_{j,k}\). This can be done efficiently by using a smaller QROM circuit (that also needs to be uncomputed), an adder and a larger "inner" QROM that actually outputs the values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inner_qrom
|
Qubrick
|
Qubrick to implement the data loading over the flattened list of nested elements. |
required |
outer_qrom
|
Qubrick
|
Qubrick to load the offsets for each set of nested data. |
required |
adder
|
Qubrick
|
Qubrick to add the offsets to contiguize the indices. Defaults to |
None
|
**kwargs
|
dict[str, Any]
|
Other key word arguments to pass to the constructor. |
{}
|
compute
compute(
index_1,
index_2,
bits_of_precision,
data,
inner_lambda_val=None,
outer_lambda_val=None,
) -> None
Compute the multiplexed data lookup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_1
|
Qubits
|
Register for the outer loop in the multiplexed QROM. |
required |
index_2
|
Qubits
|
Register for the inner loop in the multiplexed QROM. |
required |
bits_of_precision
|
int
|
Number of bits of precision for the inner QROM (the number of bits for the outer QROM is inferred). |
required |
data
|
List[List[int]]
|
Nested list of data values to load; the first dimension corresponds to the outer QROM indices and the second to the inner QROM indices. |
required |
inner_lambda_val
|
int
|
Power-of-two knob to trade off between gates and qubits. Defaults to |
None
|
outer_lambda_val
|
int
|
Power-of-two knob to trade off between gates and qubits. Defaults to |
None
|
UnaryQROM
Bases: Qubrick
A unary-encoded data-loader.
This class provides a unary QROM (Quantum Read-Only Memory) data loader, which can be used to encode data into quantum registers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments passed to the |
{}
|
compute
compute(
index_reg: Qubits,
b_of_p: int,
data: list,
ctrl: int | Qubits = 0,
*,
clean: Qubits | None = None,
)
This method loads the given data into the quantum register using unary encoding.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
The index register, encoded in unary. |
required |
b_of_p
|
int
|
The number of bits of precision per item to be loaded. |
required |
data
|
list
|
A list of integers representing the data to be loaded. |
required |
ctrl
|
int | Qubits
|
A control register for conditional loading.
Defaults to |
0
|
clean
|
Qubits | None
|
Qubits encoding the output data. If left as |
None
|
DysonSeriesLCU
Bases: Qubrick
A Dyson Series LCU Qubrick with a unary version of the truncation register.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prepare
|
Qubrick
|
a prepare qubrick for Dyson Series. |
required |
select
|
Qubrick
|
a select qubrick for Dyson Series. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Apply Dyson Series.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
register
|
CompositeRegister
|
a composite register for Dyson Series. |
required |
data
|
DysonSeriesData
|
Dataclass for the DysonSeries operator parameters. |
required |
ctrl
|
(Qubits, int)
|
a register to control this operation on. Default to |
0
|
DysonSeriesPrepareBinary
Bases: Qubrick
A modified version of the Dyson series expansion as in arXiv:1805.00675.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sort
|
Qubrick
|
a qubrick implementing quantum sort. |
None
|
prepare
|
Qubrick
|
prepare qubrick to implement the prepare oracle for |
None
|
usp
|
Qubrick
|
a qubrick that prepares a uniform state. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Apply the Dyson series prepare operator with binary version of the truncation register.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
register
|
CompositeRegister
|
register for Dyson series indexing (binary). |
required |
data
|
DysonSeriesData
|
Dataclass for the DysonSeries operator parameters. |
required |
ctrl
|
(Qubits, int)
|
A register to control this operation on. Default to |
0
|
Note
The control version is an optimized version when an input register is 0.
If the input register is not 0, the gates will be applied.
DysonSeriesPrepareUnary
Bases: Qubrick
A modified version of the Dyson series expansion as in arXiv:1805.00675.
Uses the PrepareClockState Qubrick as its subroutine to encode probabilities.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sort
|
Qubrick
|
a qubrick implementing quantum sort. |
None
|
prepare
|
Qubrick
|
prepare qubrick to implement the prepare oracle for |
None
|
usp
|
Qubrick
|
a qubrick that prepares a uniform state. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Apply the Dyson series prepare operator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
register
|
CompositeRegister
|
register for Dyson series indexing. |
required |
data
|
DysonSeriesData
|
Dataclass for the DysonSeries operator parameters. |
required |
ctrl
|
(Qubits, int)
|
A register to control this operation on. Default to |
0
|
Note
The control version is an optimized version when an input register is 0.
If the input register is not 0, the gates will be applied.
DysonSeriesSelectBinary
Bases: Qubrick
A modified version of the Dyson series expansion as in arXiv:1805.00675.
Note
If flagging time collisions, a flag qubrick is placed before the DysonSeriesSelectBinary
in the binary version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
strategy_cg
|
class
|
strategy to apply compression gadget subroutine. |
required |
flag
|
Qubrick
|
a binary version of a flag to mark time collisions in the time-discretization register. Flagging time collisions is optional. |
None
|
adder
|
Qubrick
|
a qubrick implementing add/subtract operation. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Apply the Dyson series select operator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
register
|
CompositeRegister
|
register (binary) for Dyson series indexing. |
required |
data
|
DysonSeriesData
|
Dataclass for the DysonSeries operator parameters. |
required |
ctrl
|
(Qubits, int)
|
A register to control this operation on. Default to |
0
|
DysonSeriesSelectUnary
Bases: Qubrick
A modified version of the Dyson series expansion as in arXiv:1805.00675.
Note
If flagging time collisions, a flag qubrick is placed after the DysonSeriesSelectUnary
in the unary version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fast_forward_exp
|
Qubrick
|
a qubrick implementing the time-evolution of the fast-forwardable part of the Hamiltonian. |
required |
lcu
|
Qubrick
|
a block-encoding subroutine for appliying Hamiltonian to the sustem register. |
required |
flag
|
Qubrick
|
a unary version of a flag to mark time collisions in the time-discretization register. Flagging time collisions is optional. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Apply the Dyson series select operator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
register
|
CompositeRegister
|
register for Dyson series indexing (unary version). |
required |
data
|
DysonSeriesData
|
Dataclass for the DysonSeries operator parameters. |
required |
ctrl
|
(Qubits, int)
|
A register to control this operation on. Default to |
0
|
FlagCollisionsBinary
Bases: Qubrick
A FlagCollisionsBinary Qubrick to reflect (time) collisions.
Implementation of the collision functionality as described in "Optimized quantum algorithms for simulating the Schwinger effect" research paper (internal document).
Note
For the DysonSeriesBinary logic, the flag is to applied before the application of Hamiltonians, in contrast to DysonSeriesUnary logic.
compute
Construct the Qubrick.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discret_reg
|
Qubits
|
registers to be compared (registers where time collisions may occure). |
required |
trunc_reg
|
Qubits
|
register indicating the value to compare up to. |
required |
ctrl
|
(Qubits, int)
|
a register to control this operation on. Default to |
0
|
Note on convention
The resulting register, flag, stores 1 if at least one collision occured, 0 otherwise.
FlagCollisionsUnary
Bases: Qubrick
A FlagCollisions Qubrick to reflect (time) collisions.
Implementation of the collision functionality as described in "Optimized quantum algorithms for simulating the Schwinger effect" research paper (internal document).
Note
for unary version of the DysonSeries (unary version of the truncation register).
compute
Construct the Qubrick.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
discret_reg
|
Qubits
|
registers to be compared (registers where time collisions may occure). |
required |
trunc_reg
|
Qubits
|
register indicating the value to compare up to. |
required |
ctrl
|
(Qubits, int)
|
a register to control this operation on. Default to |
0
|
Note on convention
The resulting register, flag, stores 1 if at least one collision occured, 0 otherwise.
Rz
Bases: Qubrick
Implementation of a direct Rz rotation using the built-in rz method.
This provides a simple interface for rotations that wraps the native rz gate.
RzAdder
Bases: Qubrick
Implementation of Rz rotation using an adder-based approach.
This uses the rotation catalyst state and an adder to implement an Rz rotation on the target register.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adder
|
Qubrick
|
Qubrick for implementing the addition in PGA. |
None
|
**kwargs
|
dict[str, Any]
|
Extra key word arguments for the Qubrick constructor. |
{}
|
ComputeHammingWeightBinaryRecursion
Bases: Qubrick
Quantum circuit to compute the Hamming Weight of a register that uses roughly O(N/2) ancillae and O(N) Toffoli.
This Qubrick computes the hamming weight of a quantum register (coherently) based on the algorithm outlined in this paper: Boyar, Joan, and René Peralta. "The exact multiplicative complexity of the Hamming weight function." This is a truly recursive algorithm that computes the hamming weight of a register by splitting it into three separate registers: U, V, and M. The third register, M, is of size 1 and is just an arbitrary qubit in the original register. Reigsters U and V are then an even split of qubits in the original register excluding the M qubit. The hamming weight is then computed as H(U) + H(V) + M where H(U) and H(V) are the hamming weight of U and V which are computed by calling the hamming weight computation function recursively.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adder
|
Qubrick
|
|
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the Hamming Weight.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_register
|
Qubits
|
The target qubit register to compute the hamming weight of. |
required |
ctrl
|
Qubits or int
|
Quantum control conditions |
0
|
Note
- Allocates a quantum register storing the hamming weight
ComputeHammingWeightGroupOfThrees
Bases: Qubrick
Quantum circuit to compute the Hamming Weight of a quantum register that uses roughly N ancillae and O(N) Toff.
This Qubrick computes the hamming weight of a quantum register (coherently). This is a recursive algorithm that groups qubits into batches of the 3 and computes the hamming weight of these qubits. The carry bit in this output is upgraded to the "next level" while the low-bit is tossed back into the current group of qubits. This process is repeated until all low-bits at the current level have been added and we are left with only one bit - this becomes the low bit in our hamming weight register. The process is then repeated on all of the carry bits that were upgraded to the "next level". This process is repeated until there are no more carry bits that get upgraded. This algorithm is described in arXiv:1709.06648.
compute
Compute the Hamming Weight.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_register
|
Qubits
|
The target qubit register to compute the hamming weight of. |
required |
ctrl
|
Qubits or int
|
Quantum control conditions |
0
|
Note
- Allocates a quantum register storing the hamming weight
- If qubrick is controlled and the user wants black box cost, then the black box cost will be just naively counted from operations
ComputeHammingWeightNaive
Bases: Qubrick
Naive/Qubit-efficient circuit to compute the Hamming Weight of a quantum register.
This Qubrick computes the hamming weight of a quantum register (coherently). The structure of this algorithm is to initialize a register of size log(N + 1) for an N qubit register and then traverse serially through the qubits in the target register and perform controlled adders onto the newly allocated ancilla register such that the value of the qubit in the target register is added into the value of the hamming weight register.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adder
|
Qubrick
|
|
GidneyAdd()
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the Hamming Weight.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_register
|
Qubits
|
The target qubit register to compute the hamming weight of. |
required |
ctrl
|
Qubits or int
|
Quantum control conditions |
0
|
Note
- Allocates a quantum register storing the hamming weight
HammingWeightPhasing
HammingWeightPhasing(
angle,
rot_is_rz: bool = False,
hamming_weight_qubrick=None,
use_catalyst_state: bool = False,
catalyst_state_reg=None,
use_padding: bool = False,
use_black_box: bool = False,
**kwargs,
)
Bases: Qubrick
Implement a stack of rotations of the same angle using hamming weight phasing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
angle
|
float | RotationAngle
|
An angle specifying the angle of the rotations |
required |
rot_is_rz
|
bool
|
Flag to determine if attempting to perform Rz rotations or phase gates |
False
|
hamming_weight_qubrick
|
Qubrick
|
A Qubrick that computes the hamming weight of a register |
None
|
use_catalyst_state
|
bool
|
A flag to determine if the Phasing circuit should be used to implement the growingtower of rotations. |
False
|
catalyst_state_reg
|
Qubits
|
The catalyst state for the PhaseC circuit |
None
|
use_padding
|
bool
|
A flag to determine if the Hamming Weight register should be padded with clean ancilla so that the size is consistent with the size of the catalyst state. If it is not padded, then a single phase gate needs to be applied during the PhaseC circuit. If it is padded, then the rotations should be completely decomposed via Toffolis when adding onto the catalyst state assuming the catalyst state is large enough to implement the angle passed in exactly. If the catalyst state is not large enough based on the precision of the angle, I believe a rotation is still required. |
False
|
use_black_box
|
bool
|
Uses black box AV counts if set to True. Default is False. |
False
|
**kwargs
|
dict[str, Any]
|
Additonal Qubrick kwargs |
{}
|
PhasingCircuit
Bases: Qubrick
Implement the phasing circuit.
Notes
- See under section "Additional basis rotations."
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_angle
|
float | RotationAngle
|
An angle specifying the base angle of the growing tower of rotations |
required |
rot_is_rz
|
bool
|
Flag to determine if attempting to perform Rz rotations or phase gates |
False
|
use_black_box
|
bool
|
Uses black box AV counts if set to True. Default is False. |
False
|
**kwargs
|
dict[str, Any]
|
Additonal Qubrick kwargs |
{}
|
base_angle
property
writable
Angle specifying the base angle of the growing tower of rotations.
compute
compute(
target_reg: Qubits,
catalyst_reg: Qubits,
ctrl: Qubits | int = 0,
final_qubits: Qubits | int = 0,
)
Use the phasing circuit to implement a tower of growing rotations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_reg
|
Qubits
|
The state to implement the rotations upon |
required |
catalyst_reg
|
Qubits
|
The catalyst state to use which is specific to the base angle being implemented |
required |
ctrl
|
int or Qubits
|
Classical or Quantum control conditions |
0
|
final_qubits
|
Qubits
|
If passed in, these are the three qubits on which we just perform Z, S, and T directly instead of adding on to the catalyst state. |
0
|
Notes
- The implemented circuit applies rotations of base_angle(2*i) for the i'th qubit of the target_reg where i runs from 0 to len(target_reg) - 1.
LKSMultiplexor
Bases: Qubrick
Multiplexor using data-lookup oracles.
The construction is detailed in arXiv:1812.00954 . Circuit described in Appendix D.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qrom
|
Qubrick
|
Data-loader for loading angles to bits_of_precision-bits of precision. |
required |
gate
|
op
|
Rotation gate type to use in multiplexed rotations. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute circuit for LKS multiplexor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Index register. |
required |
tgt
|
Qubits
|
Register to apply rotations onto. |
required |
angles
|
list or None
|
List of angles to supply to rotations. |
required |
bits_of_precision
|
int
|
Bits of precision for rotations. |
required |
lambda_val
|
int
|
Power-of-two knob to trade off between gates
and qubits. If |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
Note
We want to apply single-qubit \(\text{RY}\) rotations conditioned on different significant bits. We truncate the exact angle and obtain an integer approximation of it, and so, each angle we apply is \(\frac{2\pi a_k} {2^{k + 1}}\). However, we express \(\text{RY}\) rotations as \(\text{RY}(\theta) = e^{iY \frac{\theta}{2}}\). If you account for this factor of 2 in the denominator, and also convert from radians to degrees \((\frac{180}{\pi})\), you end up using:
- \(\text{angle} = \frac{\frac{2\pi a_k}{2^{k + 1}}}{2} \times \frac{180}{\pi}\)
- Simplified: \(\text{angle} = \frac{180 a_k}{2^{k + 1}}\)
LKSStatePrep
Bases: Qubrick
State preparation detailed in arXiv:1812.00954 .
This routine works for real, positive coefficients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coeffs
|
list or None
|
List of coefficients to load into state. |
required |
mplxr
|
Qubrick
|
Multiplexor to use in state prep. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute circuit for LKS state prep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qbits
|
Qubits
|
Qubits to prep state on. |
required |
**mplxr_kwargs
|
dict
|
Dictionary with keyword arguments to pass to the multiplexor. |
{}
|
Other Parameters:
| Name | Type | Description |
|---|---|---|
bits_of_precision |
int
|
Bits of precision for rotations. |
lambda_val |
int
|
Power-of-two knob to trade off between gates
and qubits. If |
MajoranaFermionOperator
Bases: Qubrick
The Majorana Fermion Operator shown in Fig. 9 of arXiv:1805.03662 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operator
|
callable
|
A function implementing an operator taking in two arguments: (1) the qubit register
(2) the control conditions. Typically either the |
required |
multiplexor_cls
|
Qubrick
|
The class for a Qubrick that implements multiplexing |
required |
**kwargs
|
dict[str, Any]
|
Additional Qubrick kwargs |
{}
|
compute
Compute the Majorana Fermion Operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
The qubit register that represents the indices to multiplex over |
required |
target_reg
|
Qubits
|
The qubit register that the Majorana Fermion Operator gets applied onto. |
required |
ctrl
|
Qubits or int
|
Additional classical or quantum control conditions. Defaults to |
0
|
MultiplexedAliasSampling
Bases: Qubrick
Implements the multiplexed alias sampling subroutine for multiplexed arbitrary state preparation.
Overview
The goal of this protocol is to take a list of lists of coefficients (probabilities corresponding to the squares of statevector amplitudes), load these coefficients using QROM, and prepare the state formed as the superposition of the states defined by each list of coefficients. This method is heavily based on the Alias Sampling technique used in quantum computing.
Steps of the Routine
Assuming familiarity with regular alias sampling, the steps are:
-
Superposition Preparation:
MultiplexedUSPis used to prepare a superposition of uniform superposition states multiplexed over indices \( i \).- The dimension of the \( i \)th USP state corresponds to the length of the coefficients for the \( i \)th state that we want to prepare.
-
Computing
altandkeepValues:- We calculate the
altandkeepvalues for each set of coefficients. - The size of the
altregister is buffered to fit the largest value for all states in superposition. - This is managed by bit-shifting the
keepvalues by this maximum value, similar to regular alias sampling.
- We calculate the
-
Multiplexor of Multiplexors:
- We load the
altandkeepvalues in superposition using the construction from arXiv:2007.14460.
- We load the
-
Partitioning QROM Output:
- The multiplexed QROM output is partitioned into
altandkeepregisters.
- The multiplexed QROM output is partitioned into
-
Creating a Coin Flip State:
- Hadamards are applied to create a uniform superposition in the coin flip register.
-
Conditional Swapping:
- A comparator checks whether
coin_toss_regis less thankeep_reg. - If true, the input
prep_regis swapped withalt_reg.
- A comparator checks whether
Note
- This construction is based on step 3 in the THC paper.
- As implemented, this routine is deterministic. However, in the reference above, it only succeeds conditioned on a success flag.
- The success flag comes from the comparator in
MultiplexedUSP. - Currently, this always succeeds because rotations are directly implemented.
- Once synthesis is introduced, alias sampling will succeed only conditionally based on the USP.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
multiplexed_usp
|
Qubrick
|
A subroutine implementation for multiplexed USP. |
required |
multiplexed_qrom
|
Qubrick
|
A subroutine implementation for multiplexed QROM. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
compute(
prep_reg,
index,
data_reg,
data,
bit_precision,
inner_lambda_val=None,
outer_lambda_val=None,
) -> None
Compute the multiplexed alias sampling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prep_reg
|
Qubits
|
Register in which we want to prepare our superposition of states. |
required |
index
|
Qubits
|
Register containing the coefficients for the multiplexing loop. |
required |
data_reg
|
Qubits
|
Register with the different |
required |
data
|
List[List[int]]
|
A list of lists of coefficients representing each of the states to be prepared in superposition. |
required |
bit_precision
|
int
|
Number of bits of precision to be used in the alias sampling discretization procedure. |
required |
inner_lambda_val
|
int
|
Power-of-two knob to trade off between gates and qubits for the inner loop in
multiplexed QROM. Defaults to |
None
|
outer_lambda_val
|
int
|
Power-of-two knob to trade off between gates and qubits for the outer loop in
multiplexed QROM. Defaults to |
None
|
Contiguizer
Bases: Qubrick
Given an input register, produce a new register with 1s from the most significant bit down to 0.
This routine comes from:
"Even more efficient quantum computations of chemistry through tensor hypercontraction" (arxiv:2011.03494) See, see step 3.(a) of the double factorization compilation in Appendix C.
The motivation behind the routine is as follows: in regular USP, we apply Hadamard gates on the input register as
the first step in the routine. The number of Hadamards is determined by the bit-length of the number of states
\(d\), so \(d=10=1010\) would require Hadamards on 4 qubits in the first step of the USP protocol. When
multiplexing, we could in principle have numbers with different bit lengths over which we multiplex, meaning that
we would need different numbers of Hadamard gates. The solution to implement this is to initialize a new register
(copy in this qubrick) and to prepare a state which has 1's on all the bits up to and including the bit-length
of \(d\) (or more precisely, a superposition over such states for all \(d\) over which we are
multiplexing). This register can then be used to apply a sequence of controlled Hadamards such that the appropriate
number of Hadamards are applied for each value of \(d\).
As an example, say we are multiplexing over two values, \(d_1=2\) and \(d_2=10\). 2 has a bit length of 2
and 10 has a bit length of 4, so the contiguizer would realize a superposition \(|0011\rangle + |1111\rangle\).
Notice that for each value \(d_i\), the value loaded into the state is (1 << d_i.bit_length()) - 1.
compute
Compute the contiguizer.
Takes an target_reg register and produces a new register (copy_reg) with 1's corresponding to the bit
lengths of the values encoded in the register (loaded in superposition).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_reg
|
Qubits
|
Register encoding the data to be multiplexed over. |
required |
ctrl
|
Qubits or int
|
Optional register to control on. Defaults to |
0
|
MultiplexedRealUSP
Bases: Qubrick
Qubrick to perform multiplexed USP.
Note
- Uses the
RealUSPflavor of USP from "Even more efficient quantum computations of chemistry through tensor hypercontraction" arxiv:2011.03494.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contiguizer
|
Qubrick
|
Qubrick instance to generate the contiguized register. Defaults to instance of Contiguizer. |
None
|
multiplexor
|
Qubrick
|
Qubrick class to perform the multiplexing. Defaults to ZeroAncMultiplexor. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
compute(
psi,
index_reg,
data_reg,
data,
rotator=None,
succ_reg=None,
error_param=None,
ctrl: int = 0,
) -> None
Generate a superposition of USPs with values given by data.
The idea behind multiplexed USP is to take a list of dimensions d, and for each to prepare a d-dimensional
uniform state in a coherent superposition. This superposition will be loaded into the psi register. Two
additional registers must be passed in: index_reg, which is used to perform the multiplexing and
data_reg, which contains an encoding of all of the d values (e.g. as loaded in via QROM).
To illustrate the idea, let's use a simple worked example. Say we have data=[2, 3]. We want to prepare a
superposition of states
and
Let us assume for simplicity that index_reg has been prepared in a uniform superposition state.
Then our target is to prepare the state
or
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
The register on which the superposition of uniform states is to be prepared. |
required |
index_reg
|
Qubits
|
The register used to load the indices for the multiplexing. |
required |
data_reg
|
Qubits
|
A register with the different values of |
required |
data
|
List[int]
|
List of dimensions for each of the USPs we are multiplexing over. |
required |
rotator
|
Qubits
|
Register to perform rotation on. Defaults to |
None
|
succ_reg
|
Qubits
|
Qubit to herald success. Defaults to |
None
|
error_param
|
float or int
|
Parameter determining the accuracy of truncated rotation
angles. If |
None
|
ctrl
|
Qubits or int
|
Optional register to control on. Defaults to |
0
|
Note
The effect of setting various default args has not been tested.
MultiplexedUSP
Bases: Qubrick
Qubrick to perform multiplexed USP.
Note
- Uses the
USPflavor of USP from "Encoding Electronic Spectra in Quantum Circuits with Linear T Complexity" (arXiv:1805.03662).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
multiplexor
|
Qubrick
|
Qubrick class to perform the multiplexing. Defaults to ZeroAncMultiplexor. |
None
|
contiguizer
|
Qubrick
|
Qubrick instance to generate the contiguized register. Defaults to instance of Contiguizer. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Generate a superposition of USPs with values given by data.
The idea behind multiplexed USP is to take a list of dimensions d, and for each to prepare a d-dimensional
uniform state in a coherent superposition. This superposition will be loaded into the psi register. Two
additional registers must be passed in: index_reg, which is used to perform the multiplexing and
data_reg, which contains an encoding of all of the d values (e.g. as loaded in via QROM).
To illustrate the idea, let's use a simple worked example. Say we have data=[2, 3]. We want to prepare a
superposition of states \(\frac{1}{\sqrt{2}}(|00\rangle + |01\rangle)\) and
\(\frac{1}{\sqrt{3}}(|00\rangle + |01\rangle + |10\rangle)\). Let us assume for simplicity that
index_reg has been prepared in a uniform superposition state. Then our target is to prepare the state
$$
\frac{1}{\sqrt{2}}(\frac{1}{\sqrt{2}}(\ket{00} + \ket{01}) + \frac{1}{\sqrt{3}}(\ket{00} + \ket{01} + \ket{10})
$$
, or
\(\frac{1}{2\sqrt{6}}(|00\rangle + |01\rangle) + \frac{1}{\sqrt{6}}(|10\rangle)\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
The register on which the superposition of uniform states is to be prepared. |
required |
index_reg
|
Qubits
|
The register used to load the indices for the multiplexing. |
required |
data_reg
|
Qubits
|
A register with the different values of |
None
|
data
|
List[int]
|
List of dimensions for each of the USPs we are multiplexing over. |
None
|
ctrl
|
Qubits or int
|
Optional register to control on. Defaults to |
0
|
data_bits
|
Qubits
|
Deprecated argument name for |
None
|
Note
The effect of setting various default args has not been tested.
BinaryTreeMultiplexor
Bases: Qubrick
Optimized multiplexing based on Fig. 7 in arXiv:1805.03662.
compute
compute(
index_reg: Qubits,
multiplex_function: Callable,
used_indices: list[int] | None = None,
ctrl: Qubits | int = 0,
)
Compute the binary tree multiplexing circuit.
We account for various cases:
- There is no data to load (exit the routine).
- Loading a single item does not require this hefty machinery.
- Loading two items without a control is similarly cheap to the single-item-case.
- Loading n > 2 items without a control.
- Loading n > 1 items with a control.
The bottom two cases are handled by calling workhorse methods in this class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register storing the values over which the multiplexing is performed. |
required |
multiplex_function
|
Callable
|
A function which takes an index and then index register and performs the operation associated with that index. |
required |
used_indices
|
list
|
List of indices corresponding to terms where the operators are actually being applied. |
None
|
ctrl
|
(int, Qubits)
|
Control for \(\text{SELECT}\). Defaults to 0. |
0
|
ConditionallyCleanMultiplexor
Bases: Qubrick
Multiplexor utilizing conditionally clean construction as presented in arxiv:2407.17966.
See Figure 9 in reference. This qubrick works by constructing the first relevant index as aggregated conditions and then applies the corresponding data conditioned on this. Then it sequentially moves through the relevant indices by finding the MSB difference, undoing the structure to this point, and then redo-ing with the new condition utiliing the partial_compute() function.
Notes
This should be called with the filter '>>hermitian-window-filter>>' to take advantage of the cancellations that occur when you replace one condition with the next. This does the minimal work before calling the filter without hardcoding the cancellations with a maximum filter window required that is linear in the number of qubits in index register. Hardcoding like in the BinaryTreeMultiplexor requires more care as gates that begin each layer in the conditionally clean structure include adjacent bits such that the gate that switches branch for bit i, will need to be aware of the higher bit (i-1) to apply the correct cancellation.
compute
compute(
index_reg: Qubits,
multiplex_function: Callable,
used_indices: list[int] | None = None,
ctrl: Qubits | int = 0,
)
Compute the serial multiplexing circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register storing the values over which the multiplexing is performed. |
required |
multiplex_function
|
callable
|
A function which takes an index and then index register and performs the operation associated with that index. |
required |
used_indices
|
list
|
List of indices corresponding to terms where the operators are actually being applied. |
None
|
ctrl
|
(int, Qubits)
|
Control for \(\text{SELECT}\). Defaults to 0. |
0
|
GeneralMultiplexedRotationNaive
GeneralMultiplexedRotationNaive(
rot_qbk: RotationInterface
| GivensRotation[float] = None,
**kwargs,
)
Bases: Qubrick
Routine for implementing multiplexed rotations, allowing for various tradeoffs.
Attributes:
| Name | Type | Description |
|---|---|---|
rot_qbk |
RotationInterface
|
The rotation protocol compliant Qubrick used for rotation operations. |
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rot_qbk
|
RotationInterface
|
The rotation protocol compliant Qubrick used for rotation operations. |
None
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments. |
{}
|
compute
compute(
index_reg: Qubits,
target_reg: Qubits,
rotation_specs: list[RotationSpec] | None = None,
bits_of_precision: int | None = None,
*,
ctrl: Qubits | int = 0,
**kwargs,
)
Compute circuit for a naive multiplexed rotation.
Implements the naive approach to multiplexed rotations by applying each rotation conditionally based on the index register matching the rotation's mux_idx. This implementation has no constraints on target qubits or rotation specifications, offering maximum flexibility at the cost of circuit efficiency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Index register that selects which rotation to apply. |
required |
target_reg
|
Qubits
|
Target register containing all qubits where rotations may be applied. |
required |
rotation_specs
|
list[RotationSpec] | None
|
List of specifications for each rotation to be multiplexed. |
None
|
bits_of_precision
|
int | None
|
Precision for the rotation angles. |
None
|
ctrl
|
Qubits | int
|
Additional control for the entire operation (keyword-only parameter). |
0
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments. |
{}
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If rotation_specs is not provided, or if a rotation spec doesn't have a rotation Qubrick specified and no default was provided. |
GeneralMultiplexedRotationViaQROM
GeneralMultiplexedRotationViaQROM(
qrom: QROM,
rot_qbk: RotationInterface
| GivensRotation[Qubits] = None,
adder: Adder = PhaseGradientAdder(),
is_unary: bool | None = None,
**kwargs,
)
Bases: Qubrick
Optimized implementation of multiplexed rotations using QROM for angle loading.
This Qubrick implements multiplexed rotations using a QROM-based approach for efficient angle loading, significantly reducing the T-count compared to naive implementations when there are many rotations.
The implementation has specific constraints: within each multiplexer group: 1. All rotations must use the same rotation Qubrick 2. All rotations must target the same qubit indices
However, different multiplexer groups can have different target qubits and rotation Qubricks. This allows for efficient batching while maintaining some flexibility.
Attributes:
| Name | Type | Description |
|---|---|---|
qrom |
Incomplete
|
The Qubrick used for quantum ROM operations to load rotation angles. |
rot_qbk |
Incomplete
|
Default rotation protocol compliant Qubrick used for all rotations unless overridden. |
adder |
Incomplete
|
Adder Qubrick used in the rotation implementation. |
bin_to_unary |
Incomplete
|
Converter for binary to unary encoding when required by the QROM. |
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qrom
|
QROM
|
The Qubrick instance used for quantum ROM operations. |
required |
rot_qbk
|
RotationInterface | GivensRotation[Qubits]
|
Default rotation protocol compliant Qubrick to use if not specified in individual rotation specs. If None, each RotationSpec must provide its own. |
None
|
adder
|
Adder
|
Adder Qubrick used in the rotation implementation. Defaults to PhaseGradientAdder(). |
PhaseGradientAdder()
|
is_unary
|
bool | None
|
Whether to use unary encoding for the index register. If None, auto-detects from the QROM implementation. |
None
|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments passed to the Qubrick constructor. |
{}
|
compute_rotations
compute_rotations(
target_indices: list[list[int]],
angle_reg: Qubits,
target_reg: Qubits,
rot_qbks_for_batch: list[RotationInterface],
b_of_p: int,
) -> None
Apply rotation operations for each mux group using loaded angles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_indices
|
list[list[int]]
|
List of target qubit indices for each rotation. |
required |
angle_reg
|
Qubits
|
Register containing loaded angle values. |
required |
target_reg
|
Qubits
|
Target register containing qubits where rotations are applied. |
required |
rot_qbks_for_batch
|
list[RotationInterface]
|
List of rotation Qubricks to use for each rotation. |
required |
b_of_p
|
int
|
Bits of precision per rotation angle. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no rotation Qubrick is available for a rotation. |
compute
compute(
index_reg: Qubits,
target_reg: Qubits,
rotation_specs: list[RotationSpec] | None = None,
mux_data: GeneralMultiplexedRotationViaQROMConfig
| None = None,
*,
ctrl: Qubits | int = 0,
)
Compute circuit for multiplexed rotation using QROM-based implementation.
This method implements multiplexed rotations using QROM for efficient angle loading. It processes rotation specifications in batches, loads batched angle data from QROM, and applies rotations to target qubits according to the specifications.
The implementation requires that within each multiplexer group: 1. All rotations must use the same rotation Qubrick 2. All rotations must target the same qubit indices
Different multiplexer groups can have different target qubits and rotation Qubricks, allowing for flexibility while maintaining efficiency.
Note
This Qubrick supports Unary QROMs as well as Binary QROMs. If the QROM is unary it must have a is_unary attribute or you must set the is_unary flag in the init
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
The index register that selects which rotation to apply. |
required |
target_reg
|
Qubits
|
The register where rotations are applied. |
required |
rotation_specs
|
list[RotationSpec] | None
|
Specifications for each rotation. |
None
|
mux_data
|
GeneralMultiplexedRotationViaQROMConfig | None
|
Configuration data for the multiplexed rotation, including: - bits_of_precision: Precision bits per rotation angle - batches: Optional custom batching information. Ex. if you have three mux_groups ordered 0,1,2 then you can send in [[0],[1],[2]] which batches none of them together, or [[0,1],[2]] to just batch 0 and 1 together. [[0,1,2]] Would batch all of them together. Defaults to zero batching, which is [[0],[1],[2]] in the example. - lambda_val: Optional parameter for QROM optimization - ignore_last_batch_qrom_cleanup: Flag to skip final QROM cleanup |
None
|
ctrl
|
Qubits | int
|
Optional control for the entire operation. |
0
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If mux_data is not provided or contains invalid specifications. |
GeneralMultiplexedRotationViaQROMConfig
dataclass
GeneralMultiplexedRotationViaQROMConfig(
bits_of_precision: int,
lambda_val: int | None = None,
batches: list[list[int]] | None = None,
ignore_last_batch_qrom_cleanup: bool = False,
)
Encapsulates configuration data for QROM-based multiplexed rotations.
This dataclass holds all the parameters needed to configure a QROM-based multiplexed rotation: precision settings, batching strategy, and other optimization parameters.
Attributes:
| Name | Type | Description |
|---|---|---|
bits_of_precision |
int
|
Number of bits used to represent each rotation angle. |
lambda_val |
int | None
|
Optional lambda value parameter for the QROM implementation. |
batches |
list[list[int]] | None
|
Optional custom batching of rotations by group indices. If None, default batching will be used based on group indices. |
ignore_last_batch_qrom_cleanup |
bool
|
If True, skips the QROM cleanup step after the last batch for optimization purposes. Default is False. |
GivensPPRs
Bases: Qubrick
Applies the Givens rotation using Pauli Product Rotations.
This method implements the unitary:
which is equivalent to applying two single-qubit rotations, one with \( +\theta \) and the other with \( -\theta \).
compute
Apply the Givens rotation using Pauli Product Rotations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation_encoding
|
float
|
Rotation angle in degrees. |
required |
target_reg
|
Qubits
|
Two qubits to apply the rotation to. |
required |
ctrl
|
Qubits | int
|
Control qubit (default: |
0
|
GivensRotationFusedAdder
Bases: Qubrick
Implements a Givens rotation using a fused quantum adder.
This method optimizes the standard two-adder approach by using a single fused adder, reducing qubit usage and circuit depth. Instead of requiring a full carry bit, it compresses the operation into a more compact form.
Note
- This implementation requires only \( b - 1 \) bits for a \( b \)-bit approximation of \( \theta \).
- The reduced bit count results from the fused adder structure, which avoids additional carry propagation.
- However, current implementations may have basis states reversed, which requires correction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adder
|
GidneyAdd or NaiveAdd
|
The quantum adder used to update phase values.
Defaults to |
None
|
**kwargs
|
dict[str, Any]
|
Additional arguments passed to |
{}
|
compute
Apply the Givens rotation using phase gradient addition with a single fused adder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation_encoding
|
Qubits
|
Rotation angle in degrees. |
required |
target_reg
|
Qubits
|
Two qubits to apply the rotation to. |
required |
ctrl
|
Qubits | int
|
Control qubit (default: |
0
|
GivensRotationTwoAdders
Bases: Qubrick
Implements a Givens rotation using two quantum adders.
This method applies a Givens rotation by using a phase gradient register and two
quantum adders (GidneyAdd or NaiveAdd). It is particularly useful for
multiplexed rotations, allowing for efficient conditional operations on quantum states.
Note
- This implementation requires \( b + 1 \) bits for a \( b \)-bit approximation of \( \theta \).
- The extra bit accounts for the additional carry bit required in the controlled addition.
- If \( b \) bits are used, precision loss can occur due to truncation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adder
|
GidneyAdd or NaiveAdd
|
The quantum adder used to update phase values.
Defaults to |
None
|
**kwargs
|
dict[str, Any]
|
Additional arguments passed to |
{}
|
compute
Apply the Givens rotation using phase gradient addition with two adders.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation_encoding
|
Qubits
|
Rotation angle in degrees. |
required |
target_reg
|
Qubits
|
Two qubits to apply the rotation to. |
required |
ctrl
|
Qubits | int
|
Control qubit (default: |
0
|
GivensRZs
Bases: Qubrick
Implements a Givens rotation using RZ gates.
This class applies a Givens rotation using Pauli Z rotations (RZ) combined
with Clifford gates. The operation targets two qubits and implements the unitary:
This transformation can be decomposed into single-qubit RZ gates with Clifford conjugation:
- Apply a Clifford pre-rotation to transform the computational basis.
- Perform controlled
RZgates to introduce the phase shift. - Apply a Clifford post-rotation to revert to the original basis.
This method is useful in multiplexed rotations and block encoding techniques.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
dict[str, Any]
|
Additional arguments passed to |
{}
|
compute
Apply the Givens rotation using Rz gates and Clifford basis change rotations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation_encoding
|
float
|
Rotation angle in degrees. |
required |
target_reg
|
Qubits
|
Two qubits to apply the rotation to. |
required |
ctrl
|
Qubits | int
|
Control qubit (default: |
0
|
MultiplexedRotationInterface
Bases: Protocol
Protocol defining the interface for multiplexed rotation Qubricks.
MultiplexedRotation Qubricks should implement this protocol to ensure they have a consistent interface for controlling multiple rotations based on an index.
The protocol standardizes on a consistent parameter order with index register and target register as the first two parameters, followed by implementation-specific positional parameters, with the control parameter at the end. This allows for flexibility in how implementations handle their specific parameters.
OneAncMultiplexor
Bases: Qubrick
\(\text{SELECT}\) operator using a single, clean ancilla.
Circuit shown in Fig. (1.a) in arXiv:1812.00954.
compute
compute(
index_reg: Qubits,
multiplex_function: Callable,
used_indices: list[int] | None = None,
ctrl: Qubits | int = 0,
)
Compute a multiplexing circuit using a single, clean ancilla.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register storing the values over which the multiplexing is performed. |
required |
multiplex_function
|
callable
|
A function which takes an index and then index register and performs the operation associated with that index. |
required |
used_indices
|
list
|
List of indices corresponding to terms where the operators are actually being applied. |
None
|
ctrl
|
(int, Qubits)
|
Control for \(\text{SELECT}\). Defaults to 0. |
0
|
RotationInterface
Bases: Protocol
Protocol defining the interface for rotation Qubricks.
Rotation Qubricks should implement this protocol to ensure they have a consistent interface for use in multiplexed rotations.
The protocol allows for additional custom arguments via **kwargs to accommodate different rotation implementations with specialized parameters.
RotationSpec
dataclass
RotationSpec(
group_idx: int,
mux_idx: int,
target_qubits: list[int],
angle: float,
rot_qbk: RotationInterface | None = None,
)
Specification for a single rotation in a multiplexed rotation circuit.
This dataclass holds all information needed to define a single rotation operation within a multiplexed rotation circuit, including its group, multiplexing index, target qubits, angle, and optional custom rotation Qubrick.
Attributes:
| Name | Type | Description |
|---|---|---|
group_idx |
int
|
Index of the group this rotation belongs to. Groups allow batched execution of compatible rotations. |
mux_idx |
int
|
Multiplexing select index - when the index register equals this value, the rotation will be applied. |
target_qubits |
list[int]
|
List of qubit indices where the rotation should be applied. |
angle |
float
|
Rotation angle in radians. |
rot_qbk |
RotationInterface | None
|
Optional custom rotation Qubrick to use for this specific rotation. If None, the default rotation Qubrick from the parent class will be used. |
SawtoothMultiplexor
Bases: Qubrick
Unoptimized multiplexor from Fig. 5 in arXiv:1805.03662.
For some function, f, which returns an operator associated with an integer index, performs: \(\text{SELECT}|l\rangle|\psi\rangle \rightarrow |l\rangle f(l)|\psi\rangle\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_index
|
(Optional, int)
|
Integer corresponding to the maximum possible index that will be multiplexed over. Defaults to None. |
None
|
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_index
|
(Optional, int)
|
Integer corresponding to the maximum possible index that will be multiplexed over. Defaults to None. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
set_max_index
Set the max index.
Sets the max_index attribute to the input arg.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_val
|
int
|
The max possible index to iterate over, given as an int. |
required |
compute
compute(
index_reg: Qubits,
multiplex_function: Callable,
used_indices: list[int] | None = None,
ctrl: Qubits | int = 0,
)
Compute the sawtooth multiplexing circuit.
We account for four cases, and some sub-cases:
- There is no data to load (exit the routine).
- Loading a single item does not require this hefty machinery.
- Loading two items without a control is similarly cheap to the single-item-case.
- All other cases will proceed with unary iteration, removing controls on the index register when possible.
The last case above has a couple of sub-cases:
(i). We (rarely, but sometimes) may determine we needn't control on any qubit for a particular index value; consider this a free lunch!
(ii). The uncontrolled version of this routine is slightly cheaper than the controlled case. We actually have additional small sub-cases here: (a). If we determine we only need to control on a single qubit for a particular index, we can directly apply that element and exit the for loop. (b). In all other cases, the uncontrolled case uses one fewer ancilla than the controlled case (and also one fewer elbow).
(iii). After accounting for one fewer qubit for the uncontrolled case, the controlled and uncontrolled case than perform the same logic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register storing the values over which the multiplexing is performed. |
required |
multiplex_function
|
callable
|
A function which takes an index and then index register and performs the operation associated with that index. |
required |
used_indices
|
list
|
List of indices corresponding to terms where the operators are actually being applied. |
None
|
ctrl
|
(int, Qubits)
|
Control for \(\text{SELECT}\). Defaults to 0. |
0
|
ZeroAncMultiplexor
Bases: Qubrick
Most naïve version of multiplexing possible.
For some function, f, which returns an operator associated with an integer index performs: \(\text{SELECT}|l\rangle|\psi\rangle \rightarrow |l\rangle f(l)|\psi\rangle\).
compute
compute(
index_reg: Qubits,
multiplex_function: Callable,
used_indices: list[int] | None = None,
ctrl: Qubits | int = 0,
)
Compute the serial multiplexing circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register storing the values over which the multiplexing is performed. |
required |
multiplex_function
|
callable
|
A function which takes an index and then index register and performs the operation associated with that index. |
required |
used_indices
|
list
|
List of indices corresponding to terms where the operators are actually being applied. |
None
|
ctrl
|
(int, Qubits)
|
Control for \(\text{SELECT}\). Defaults to 0. |
0
|
ArbitraryStatePrep
Bases: Qubrick
State preparation based on the routine in arXiv:quant-ph/0407010v1 .
Realizes:
Note
This routine prepares the desired state up to a global phase. When checking the validity of this routine, one should check fidelity rather than exact state vector matching. The other consequence is that controlling this routine will lead to (incorrect) relative phases.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
multiplexor
|
(Qubrick, None)
|
Which multiplexing scheme to use in state prep.
Defaults to |
None
|
amps
|
list or None
|
List of amplitudes to load into state. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
set_angles
Set angles if none computed. Z angles defaults to None.
compute
Compute the arbitrary state preparation circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qbits
|
Qubits
|
Qubits to operate on. |
required |
ctrl
|
Qubits or int
|
Register to control the on. Defaults to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
EfficientMultiplexedRotations
Bases: Qubrick
Decomposition of uniformly controlled rotations to single qubit rotation + CNOTs.
Corresponds to Figure 2 in arXiv:0407010 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gate
|
op or None
|
Rotation gate type to use in multiplexed rotations. Defaults to None. |
None
|
angles
|
list or None
|
List of angles to supply to rotations. Defaults to None. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the multiplexed rotation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits / int
|
Index qubits. |
required |
tgt
|
Qubits / int
|
Target qubit. |
required |
ctrl
|
(Qubits, int)
|
A register to control this operation on. Default to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
NaiveMultiplexedRotations
Bases: Qubrick
Controlled rotations from arXiv:0407010 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gate
|
op or None
|
Rotation gate type to use in multiplexed rotations. Defaults to None. |
None
|
angles
|
list or None
|
List of angles to supply to rotations. Defaults to None |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the multiplexed rotation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits / int
|
Index qubits. |
required |
tgt
|
Qubits / int
|
Target qubit. |
required |
ctrl
|
(Qubits, int)
|
A register to control this operation on. Default to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
PrepareNaive
Bases: Qubrick
State preparation based on the routine in arXiv:quant-ph/0407010v1 .
Realizes:
Warning
This function only works for real and positive coefficients
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
multiplexor
|
Qubrick
|
Which multiplexing scheme to use in state prep.
Defaults to |
None
|
coeffs
|
list or None
|
List of coefficients to load into state. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute the state preparation circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qbits
|
Qubits
|
Qubits to operate on. |
required |
ctrl
|
(Qubits, int)
|
A register to control this operation on. Default to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
BitonicPermutation
Bases: Qubrick
A routine that permutes qubit registers.
compute
compute(
target_reg: Qubits,
reg_size: int,
register_permutation_function: Callable,
ctrl: Qubits | int = 0,
)
Compute the circuit for the canonical swap-up-type permutation.
The sorting/permutation logic to perform a permutation of a register is independent of the particular quantum op used to effect a permutation. to use. This compute method exists so we can write down this logic just once and re-use it with your favorite "payload".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_reg
|
(Qubits, list)
|
Register we apply the permutation to. This register can conceptually be interpreted as a single large register, or as several registers of equal size. To facilitate this dual use, we currently allow passing a list of Qubits objects (though this is likely to be refactored). |
required |
reg_size
|
int
|
Number of bits in each target sub-register of |
required |
register_permutation_function
|
callable
|
Which quantum operation to use to effect the permutation of the target register. |
required |
ctrl
|
Optional[Qubits, int]
|
Qreg to control on. Defaults to 0. |
0
|
Note
target_reg is given as a single register or as a list of multiple registers.
PhaseGradientAdder
Bases: Qubrick
Optimized adder for use in phase gradient addition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
dict[str, Any]
|
Keyword arguments |
{}
|
compute
Circuit for optimized phase gradient adder.
This construction comes from Fig. 13 in arXiv:2007.07391.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lhs
|
QUInt | None
|
The register with the phase gradient catalyst state. May be |
required |
rhs
|
QUInt
|
The register we are adding into the phase gradient register. |
required |
ctrl
|
(Optional, int | Qubits)
|
Control register. Defaults to |
None
|
Note
- The phase gradient register is usually one qubit smaller than the rhs.
- However, there exists at least one known case where they are equal in size (ex. when using GivensRotationTwoAdders).
- When they are the same size, we can actually drop a CZ, and so, we distinguish these cases.
- For
rhstwo qubits andlhsone qubit shorter thanrhs, the Fig.~13 chain collapses to three bilinear gates (no temporary elbow). With no adder control, those arelhs.z(rhs[0]),lhs.x(rhs[0]),rhs[1].z(). With a control registerctrl(e.g. bidirectional rotation tests), mergectrlinto each gate aslhs[0].z(rhs[0] | ctrl),lhs[0].x(rhs[0] | ctrl),rhs[1].z(cond=ctrl). - For
lhsandrhsboth a single qubit, only the closing segment remains (matchingGidneyAddon one-qubitlhs).
PrepareClockState
Bases: Qubrick
Prepares a clock state.
Example
The output state will be of the form \(\sqrt{p_0}|000\rangle + \sqrt{p_1}|100\rangle + \sqrt{p_2}|110\rangle + \sqrt{p_3}|111\rangle\).
The ket-states should be understood as a unary representation of an integer. For example, \(|1110\rangle\) is 3 in decimal \(|1000\rangle\) is 1 in decimal.
Note
The controlled version only ensures \(\text{c-PREP}|+\rangle|0\rangle^{\otimes n} = |0\rangle|0\rangle^{\otimes n}+|1\rangle \text{PREP}|0\rangle^{\otimes n}\) (a.k.a. if the input state is not zero, there is still an action of this Qubrick).
compute
Prepare the clock state according to given probabilities.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
Qubits
|
Target qubits. |
required |
probs
|
list
|
List of probability, such that the output state is of the form \(\sqrt{p_0}|000\rangle + \sqrt{p_1}|100\rangle + \sqrt{p_2}|110\rangle + \sqrt{p_3}|111\rangle\). |
required |
ctrl
|
(Qubits, int)
|
Control register. Default to 0. |
0
|
PrepareWState
Bases: Qubrick
Prepares a W state.
Note
The controlled version only ensures \(\text{c-PREP}|+\rangle|0\rangle^{\otimes n} = |0\rangle|0\rangle^{\otimes n} + |1\rangle\text{PREP}|0\rangle^{\otimes n}\) (a.k.a. if the input state is not zero, there is still an action of this Qubrick).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
khot_prep
|
Qubrick
|
Qubrick to implement a Clock state. |
None
|
wpower2_prep
|
Qubrick
|
Qubrick to prepare a W state over a power-of-two number of amplitudes. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
PrepareWStatePowerTwo
Bases: Qubrick
Prepares a W state for power of two target size.
Note
The controlled version only ensures \(\text{c-PREP}|+\rangle|0\rangle^{\otimes n} = |0\rangle|0\rangle^{\otimes n} + |1\rangle\text{PREP}|0\rangle^{\otimes 2^n}\) (a.k.a. if the input state is not zero, there is still an action of this Qubrick).
CosineWindow
Bases: Qubrick
Cosine window from arxiv:2110.09590 .
compute
Executes circuit for implementing cosine window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
phase_reg
|
Qubits
|
Phase qubit register |
required |
ctrl
|
(Optional, int, Qubits)
|
Control register |
0
|
**kwargs
|
dict[str, Any]
|
Optional keyword arguments. Included to stay consistent with the arguments of window emulators. |
{}
|
RectWindow
Bases: Qubrick
Rectangular/Dirichlet window. This is the default window function for the textbook QPE.
compute
Executes circuit for implementing rectangular window.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
phase_reg
|
Qubits
|
Phase qubit register |
required |
ctrl
|
(Optional, int, Qubits)
|
Control register |
0
|
**kwargs
|
dict[str, Any]
|
Optional positional arguments. Included to stay consistent with the arguments of window emulators. |
{}
|
SineWindow
Bases: Qubrick
Qubrick for window state with the sine function over the amplitudes.
This window state can be used to achieve an optimal Holevo variance as outlined in Section II B. of arxiv:1805.03662 . See \(\Xi_m\) state.
Note
The state prepared here has a global phase of pi. Additionally, if the user does not care about having purely real or purely imaginary values in the prepared state, the rz gates can be replaced by phase gates in which case the magnitudes will be the same as the expected state, but each amplitude will be rotated by some (global) phase.
compute
Computes sine window function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_reg
|
Qubits
|
register on which the sine window state is prepared |
required |
flag_reg
|
Qubits
|
flag qubit when 0, the sine window state is prepared |
required |
ctrl
|
Qubits
|
control qubit |
0
|
use_real_amps
|
bool
|
If True, prepares real amplitudes |
False
|
**kwargs
|
dict[str, Any]
|
Optional keyword arguments |
{}
|
Note
- Needs a round of amplitude amplification.
SineWindowPhaseCatalysis
Bases: Qubrick
Qubrick for window state with the sine function over the amplitudes.
Prepared via phase catalyst register.
This window state can be used to achieve an optimal Holevo variance as outlined in Section II B. of arxiv:1805.03662 . See \(\Xi_m\) state.
The phase catalyst implementation is outlined in Appendix B of arxiv:1805.03662
Note
The state prepared here will be the same as SineWindow up to a global phase.
SineWindowQubitEfficient
Bases: Qubrick
Qubrick for window state with the sine function over the amplitudes using only two active qubits at a time.
This window state can be used to achieve an optimal Holevo variance with the construction of the circuit outlined in Section IV of arxiv:2303.12505.
WindowEmulator
WindowEmulator(
emulator_func: Callable[Concatenate[int, P], NDArray],
emulator_function_options: dict[str, Any] | None = None,
**kwargs,
)
Bases: Qubrick
Constructor for window emulator.
Note
- Check the window utils module for emulator_func options.
- Note that this Qubrick does not execute quantum operations; it directly touches the state vector and is not meant to run on a real QPU program.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
emulator_func
|
callable
|
method for computing amplitudes of a window state |
required |
emulator_function_options
|
dict[str, Any]
|
Extra keyword arguments for the emulator_func |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute amplitudes of taper state.
Note
Assumes Qubits in QC are ordered as: (1) Psi (2) Phase Register (3) All other qubits
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
phase_reg
|
Qubits
|
Phase qubit register |
required |
psi
|
Qubits
|
System register |
required |
ctrl
|
(Optional, int, Qubits)
|
Control register |
0
|
**kwargs
|
dict[str, Any]
|
Optional keyword arguments. Included to stay consistent with the arguments of window emulators. |
{}
|
Note
- Use emulators for a reasonably small number of phase qubits!
- The control version is not currently implemented
WindowStatePrep
Bases: Qubrick
General class for simulating window state via state prep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amps
|
ndarray
|
Amplitudes for window state. |
required |
state_prep
|
Qubrick
|
Qubrick to implement the state preparation for the window function. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Executes circuit for preparing window state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
phase_reg
|
Qubits
|
Phase qubit register. |
required |
ctrl
|
(Optional, int, Qubits)
|
Control register. |
0
|
**kwargs
|
dict[str, Any]
|
Optional keyword arguments. Included to stay consistent with the arguments of window emulators. |
{}
|
QPE
Bases: Qubrick
Implements the standard quantum phase estimation routine using controlled unitaries and QFT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits_of_precision
|
int
|
The number of bits to estimate the phase to. |
required |
unitary
|
Qubrick
|
The unitary for which we want to estimate the eigenphase. |
required |
window_kwargs
|
dict
|
Keyword args for window func (e.g. in case it uses amplitude amplification). Defaults to None. |
None
|
window_func
|
Qubrick
|
Which window func to apply to the initial state of the phase register. Defaults to RectWindow. |
RectWindow()
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute quantum phase estimation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
State register for the computation. |
required |
phase_reg
|
Qubits
|
Register to load the eigenphase into. |
required |
ctrl
|
(Optional, int, Qubits)
|
Register to control the QPE on. |
0
|
unitary_kwargs
|
dict[str, Any]
|
Any additional kwargs that need to be passed to the |
{}
|
Note
The control version makes no assumptions on the input states (phase register), and thus uses a naive control implementation (control on all operations). If the phase register is known to be in the zero state, one can control only phase window and the QFT or, if the RectWindow is used, one could only control the unitary.
CoherentIterativeQPE
CoherentIterativeQPE(
bits_of_precision,
unitary,
window_kwargs=None,
window_func=RectWindow(),
**kwargs,
)
Bases: Qubrick
Performs iterative QPE as shown in Fig. 16 of arxiv:2105.02859.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits_of_precision
|
int
|
The number of bits of precision to estimate the eigenphase to. |
required |
unitary
|
Qubrick
|
The unitary to compute the eigenphase of. |
required |
window_kwargs
|
dict[str, Any]
|
Key word arguments to pass to the window function. |
None
|
window_func
|
Qubrick
|
Which window func to apply to the initial state of the phase register. Defaults to RectWindow. |
RectWindow()
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute coherent iterative quantum phase estimation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
State register for the computation. |
required |
phase_reg
|
Qubits
|
Register to load the eigenphase into. |
required |
ctrl
|
(Optional, int, Qubits)
|
Register to control the QPE on. |
0
|
unitary_kwargs
|
dict[str, Any]
|
Any additional kwargs that need to be passed to the |
{}
|
Note
The control version makes no assumptions on the input states (phase register), and thus uses a naive control implementation (control on all operations). If the phase register is known to be in the zero state, one can control only phase window and the QFT.
DoublePhaseKickbackQPE
DoublePhaseKickbackQPE(
bits_of_precision,
unitary: QubitizedWalkOperator,
window_func=RectWindow(),
window_kwargs=None,
**kwargs,
)
Bases: Qubrick
Implements the double-phase kickback quantum phase estimation routine.
This version of QPE achieves m bits of precision using m qubits in the
phase register, but uses approximately half the number of queries to the unitary
than is necessary when using traditional QPE. It should be noted however that the
input unitary for this approach must be in the form of a qubitized walk operator
as outlined in Fig. 1 of arxiv:1805.03662 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits_of_precision
|
int
|
The number of bits to estimate the phase. |
required |
unitary
|
QubitizedWalkOperator
|
The unitary for which we want to estimate the eigenphase. Must be in the form of a qubitized walk operator as outlined in Fig. 1 of arxiv:1805.03662 . |
required |
window_func
|
Qubrick
|
Which window func to apply to the initial state of the phase register. |
RectWindow()
|
window_kwargs
|
dict
|
Keyword args for window func (e.g. in case it uses amplitude amplification). Defaults to None. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute QPE based on Figure 2 of arxiv:1805.03662 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
State register for the computation. |
required |
phase_reg
|
Qubits
|
Register to load the eigenphase into. |
required |
be_ancilla_reg
|
Qubits
|
State register used to implement the block encoding on psi. |
required |
ctrl
|
(Optional, int, Qubits)
|
Register to control the QPE on.
Defaults to |
0
|
kwargs
|
dict[str, Any]
|
Any additional kwargs that need to be passed to the
|
{}
|
IterativeQPE
Bases: Qubrick
Implements incoherent (measurement-based) QPE.
Warning
Conceptually, iterative quantum phase estimation should be able to be performed using a single ancilla, and
this Qubrick is capable of doing so -- however, since no values are returned from Qubricks, this
functionality is currently broken.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits_of_precision
|
int
|
The number of bits of precision to estimate the eigenphase to. |
required |
unitary
|
Qubrick
|
The unitary to compute the eigenphase of. |
required |
window_kwargs
|
dict[str, Any]
|
Key word arguments to pass to the window function. |
None
|
window_func
|
Qubrick
|
Which window func to apply to the initial state of the phase register. Defaults to RectWindow. |
RectWindow()
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute quantum phase estimation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
State register for the computation. |
required |
phase_reg
|
(Qubits, Optional)
|
Register into which the eigenphase is loaded. |
required |
ctrl
|
(Optional, int, Qubits)
|
Register to control the QPE on. |
0
|
unitary_kwargs
|
dict[str, Any]
|
Any additional kwargs that need to be passed to the |
{}
|
Note
- The control version makes no assumptions on the input states (phase register), and thus uses a naive control implementation (control on all operations). If the phase register is known to be in the zero state, one can control only phase window and the QFT.
- Classical result is: list of binary values corresponding to the
bits_of_precisionbit representation of the estimated eigenphase.
OptimizedDoublePhaseKickbackQPE
OptimizedDoublePhaseKickbackQPE(
bits_of_precision,
unitary: QubitizedWalkOperator,
window_func=RectWindow(),
window_kwargs=None,
**kwargs,
)
Bases: Qubrick
Implements an optimized version of the double-phase kickback quantum phase estimation routine.
There are two main optimizations we use here that lead to some minor gate-cost reductions:
- Subsequent applications of the controlled reflections (C-R_L) can be merged together with some simple qubit logic consisting of two CNOT gates. This means that in the middle of the circuit, we reduce the cost of applications of C-R_L (PREP^ - Refl - PREP) by approximately a factor of 2.
- Inspecting the naive DoublePhaseKickbackQPE circuit, there are often applications of PREP that are immediately followed by PREP^. With some classical logic, we can choose to not apply these gates as PREP is self-inverse.
In the same way as DoublePhaseKickbackQPE, this version of QPE achieves m bits of precision using m qubits in
the phase register, but uses approximately half the number of queries to the unitary than is necessary when using
traditional QPE. It should be noted however that the input unitary for this approach must be in the form of a
qubitized walk operator as outlined in Fig. 1 of arxiv:1805.03662 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bits_of_precision
|
int
|
The number of bits to estimate the phase. |
required |
unitary
|
QubitizedWalkOperator
|
The unitary for which we want to estimate the eigenphase. Must be in the form of a qubitized walk operator as outlined in Fig. 1 of arxiv:1805.03662 . |
required |
window_func
|
Qubrick
|
Which window func to apply to the initial state of the phase register. |
RectWindow()
|
window_kwargs
|
dict
|
Keyword args for window func (e.g. in case it uses amplitude amplification). Defaults to None. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
Compute QPE based on Figure 2 of arxiv:1805.03662 .
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
State register for the computation. |
required |
phase_reg
|
Qubits
|
Register to load the eigenphase into. |
required |
be_ancilla_reg
|
Qubits
|
State register used to implement the block encoding on psi. |
required |
ctrl
|
(Optional, int, Qubits)
|
Register to control the QPE on.
Defaults to |
0
|
kwargs
|
dict[str, Any]
|
Any additional kwargs that need to be passed to the
|
{}
|
Qubitization
Bases: Qubrick
Canonical qubitization iterate.
This Qubrick follows the canonical form of Qubitization introduced in "Hamiltonian Simulation by Qubitization" (arXiv:1610.06546) and used extensively in Lin Lin's lecture notes). This convention starts with a block encoding followed by an all-zero reflection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
block_encoding
|
Qubrick
|
Qubrick to apply the block encoding circuit. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
compute(
psi: Qubits,
be_ancilla_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
**kwargs: dict[str, Any],
)
Compute the qubitization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
Target state register. |
required |
be_ancilla_reg
|
Qubits
|
Block encoding auxiliary register. |
required |
data
|
PauliSum | list[int]
|
Hamiltonian or bitstring values to be qubitized. |
required |
ctrl
|
Qubits | int
|
Register to control the qubitization on. Defaults to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
QubitizedWalkOperator
Bases: Qubrick
Qubitization iterate.
This Qubrick uses the form introduced in "Quantum Algorithm for Spectral Measurement with Lower Gate Count" (arxiv:1711.11025).
This form is also used by the Google group for their QPE-Qubitization papers.
This form differs from the canonical Qubitization iterate (see Fig. 1 of
"Even more efficient quantum computations of chemistry through tensor hypercontraction"
(arXiv:2011.03494)), and effectively performs a qubitization
of a quantum walk, hence the name QubitizedWalkOperator.
Note
Despite being a Qubitization iterate, this Qubrick has a different signature
than the canonical Qubitization Qubrick, in that it is defined in terms of
\(\text{PREP}\) and \(\text{SELECT}\) rather than arbitrary block encodings.
Furthermore, when plugging it in to QPE, one must be careful with what initial state
is passed to QPE. When using this Qubrick, one must first call \(\text{PREP}\)'s
compute before calling QPE's compute, as this \(\text{PREP}\) effectively
prepares a portion of an eigenstate of the QubitizedWalkOperator
(or at least a state which has meaningful support on it).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state_prep
|
Qubrick
|
Qubrick to apply the state prep. |
required |
select
|
Qubrick
|
Qubrick to select the Hamiltonian terms from. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
compute
compute(
psi: Qubits,
be_ancilla_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
**kwargs: dict[str, Any],
)
Compute the qubitization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
psi
|
Qubits
|
Target state register. |
required |
be_ancilla_reg
|
Qubits
|
Block encoding auxiliary register. |
required |
data
|
PauliSum | list[int]
|
Hamiltonian or bitstring values to be qubitized. |
required |
ctrl
|
Qubits | int
|
Register to control the qubitization on. Defaults to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
BinaryTreeSelect
Bases: Qubrick
Optimized select from Fig. 7 in "Encoding Electronic Spectra in Quantum Circuits with Linear T Complexity" (arXiv:1805.03662).
compute
compute(
index_reg: Qubits,
target_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
)
Compute Select circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register determining which op in data to apply. |
required |
target_reg
|
Qubits
|
Qubit register to apply the data to. |
required |
data
|
PauliSum | list[int]
|
Hamiltonian terms expressed as a |
required |
ctrl
|
Qubits | int
|
Control register. Defaults to 0. |
0
|
ConditionallyClean
Bases: Qubrick
Select utilizing conditionally clean construction as presented in arxiv:2407.17966.
Notes
This should be called with the filter '>>toffoli-window-filter>>' to take advantage of the cancellations that occur when you replace one condition with the next. This does the minimal work before calling the filter without hardcoding the cancellations with a maximum filter window required that is linear in the number of qubits in index register.
compute
compute(
index_reg: Qubits,
target_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
)
Compute Select circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register determining which op in data to apply. |
required |
target_reg
|
Qubits
|
Qubit register to apply the data to. |
required |
data
|
(PauliSum, List[int])
|
Hamiltonian terms expressed as a
|
required |
ctrl
|
(int, Qubits)
|
Control register. Defaults to 0. |
0
|
SawtoothSelect
Bases: Qubrick
Unoptimized select from Fig. 5 in "Encoding Electronic Spectra in Quantum Circuits with Linear T Complexity" (arXiv:1805.03662).
compute
compute(
index_reg: Qubits,
target_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
)
Compute Select circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register determining which op in data to apply. |
required |
target_reg
|
Qubits
|
Qubit register to apply the data to. |
required |
data
|
PauliSum | list[int]
|
Hamiltonian terms expressed as a |
required |
ctrl
|
Qubits | int
|
Control register. Defaults to 0. |
0
|
SelectNaive
Bases: Qubrick
Most naïve version of \(\text{SELECT}\) possible.
If the data to be loaded is given as a list of Hamiltonian terms, performs the transformation
If the data to be loaded as given as a list of bit values \(data\), performs the transformation
compute
compute(
index_reg: Qubits,
target_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
)
Compute Select circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register determining which op in data to apply. |
required |
target_reg
|
Qubits
|
Qubit register to apply the data to. |
required |
data
|
PauliSum | list[int]
|
Hamiltonian terms expressed as a |
required |
ctrl
|
Qubits | int
|
Control register. Defaults to 0. |
0
|
SelectOneAnc
Bases: Qubrick
\(\text{SELECT}\) operator using a single, clean auxiliary qubit.
Circuit shown in Fig. 1A in "Trading T gates for dirty qubits in state preparation and unitary synthesis" (arXiv:1812.00954).
compute
compute(
index_reg: Qubits,
target_reg: Qubits,
data: PauliSum | list[int],
ctrl: Qubits | int = 0,
)
Compute Select circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
Qubits
|
Qubit register determining which op in data to apply. |
required |
target_reg
|
Qubits
|
Qubit register to apply the data to. |
required |
data
|
PauliSum | list[int]
|
Hamiltonian terms expressed as a |
required |
ctrl
|
Qubits | int
|
Control register. Defaults to 0. |
0
|
BitonicSort
Bases: Qubrick
Qubrick for performing a bitonic sort on a list of qubits.
unsort
Uncompute sort a list of qubit registers.
This performs a measurement in the X basis for each record qubit. If the outcome is one, it will require a phase-fixup performed by a comparator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
regs_list
|
list[Qubits]
|
List of qubit registers to unsort. |
required |
ctrl
|
(int, Qubits)
|
Control qubit for the routine. |
0
|
compute
Sort a list of qubit registers.
Sort in ascending order if direction = 0, and descending otherwise. See : https://en.wikipedia.org/wiki/Bitonic_sorter#/media/File:BitonicSort.svg
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
regs_list
|
list[Qubits] or VectorRegister
|
List of qubit registers to sort. |
required |
direction
|
int
|
Direction of the sort (0-ascending vs 1-descending). |
required |
ctrl
|
(int, Qubits)
|
Control qubit for the routine. Defaults to 0. |
0
|
Note
This assumes same size register for all registers in regs_list.
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.
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
|
PauliSumTrotterStrategy
Implementation of a TrotterStrategy for the simplest case of looping through Hamiltonian terms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hamiltonian
|
PauliSum
|
PauliSum representation of the Hamiltonian to be Trotterized. The order of the terms in the PauliSum determines the order in which the Trotterized terms will be applied, with the coefficients determining their magnitude. |
required |
trotter_order
|
int
|
The order of the Trotterization. |
None
|
TrotterQuery
TrotterQuery(
trotter_strategy: TrotterStrategy | None = None,
trotter_order: int | None = None,
hamiltonian: PauliSum | None = None,
**kwargs,
)
Bases: Qubrick
Qubrick for implementing a Suzuki-Trotter approximation of an exponentiated Hamiltonian.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trotter_strategy
|
TrotterStrategy | None
|
A class that implements a |
None
|
trotter_order
|
int
|
The order of Trotterization. |
None
|
hamiltonian
|
PauliSum
|
The Hamiltonian expressed as a PauliSum. |
None
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
trotter_strategy
property
Set the trotter_strategy property so it can't be modified.
compute
compute(
system: Qubits,
steps: int,
evo_time: int,
ctrl: Qubits | int = 0,
trotter_order: int | None = None,
)
Execute the Suzuki-Trotter circuit.
Performs first and second order Trotterization directly. For higher orders, uses recursive calls to generate the appropriate product of operators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
Qubits
|
Qubits the Hamiltonian is acting on. |
required |
steps
|
int
|
The number of Trotter steps. |
required |
evo_time
|
int
|
(int): The total evolution time. |
required |
ctrl
|
(Qubits, int)
|
Qubit register to control evolution on. Defaults to 0. |
0
|
trotter_order
|
int
|
The order of Trotterization. If not set,
uses the Qubrick attribute |
None
|
TrotterStrategy
Bases: Protocol
Interface for applying unitary terms in Trotterization.
USP
Bases: Qubrick
Qubrick for performing Uniform State Preparation.
From Fig. 12 in "Encoding Electronic Spectra in Quantum Circuits with Linear T Complexity" (arXiv:1805.03662).
compute
Prepare a uniformly distributed state.
Conceptually, starts by factoring \(d = 2^k L\), although this explicit calculation has been replaced by
the num_trailing_zeros and highest_bit functions for better performance.
Just applying Hadamard gates creates the desired equal superposition over k of the qubits.
For the remaining qubits we need to also perform amplitude amplification to keep only basis states with value < d.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
int
|
Desired number of uniform terms. |
required |
target_qreg
|
Qubits
|
The register to operate on. |
required |
error_param
|
float
|
Parameter determining the accuracy of truncated rotation
angles. If |
None
|
ctrl
|
Qubits or int
|
Register to control the USP on. Defaults to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the register passed in is too small. |
Note
The effect of setting various default args has not been tested. Creates desired state up to global phase.
RealUSP
Bases: Qubrick
Qubrick for performing Uniform State Preparation.
From "Even more efficient quantum computations of chemistry through tensor hypercontraction" (arxiv:2011.03494).
Note
- This is the version based on the instructions (steps 1-7) under Eq. A15 of Appendix A.
- A circuit diagram showing a similar implementation (but over two target registers) is shown in Fig. (3).
compute
compute(
d,
target_qreg,
rotator=None,
succ_reg=None,
error_param=None,
ctrl: int = 0,
**kwargs,
) -> None
Prepare a uniformly distributed state.
Conceptually, starts by factoring \(d = 2^k L\), although this explicit calculation has been replaced by
the num_trailing_zeros and highest_bit functions for better performance.
Just applying Hadamard gates creates the desired equal superposition over k of the qubits.
For the remaining qubits we need to also perform amplitude amplification to keep only basis states with value < d.
Utilizes one auxiliary qubit, the 'rotator', such that CZ gates perform the required reflections.
This routine uses RY rotations, resulting in only real amplitudes.
If no error_param is provided, the rotations are treated as ideal and the probability of success is 1.0.
If an error_param is provided, the probability of success will be <=1.0 and a flag qubit will store the result via a comparator.
This qubit can be optionally provided via succ_reg.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
int
|
The number of nonzero terms required. |
required |
target_qreg
|
Qubits
|
The register to operate on. |
required |
rotator
|
Qubits
|
Register to perform rotation on. Defaults to |
None
|
succ_reg
|
Qubits
|
Qubit to herald success. Defaults to |
None
|
error_param
|
float
|
Parameter determining the accuracy of truncated rotation
angles. If |
None
|
ctrl
|
Qubits or int
|
Register to control the USP on. Defaults to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the register passed in is too small. |
Note
The effect of setting various default args has not been tested.
ZeroAncillaUSP
Bases: Qubrick
Qubrick for performing Uniform State Preparation without auxiliary qubits.
Adapted from "An efficient quantum algorithm for preparation of uniform quantum superposition states" (arxiv:2306.11747).
compute
Prepare a uniformly distributed state.
Utilizes binary decomposition of \(d\), controlled Ry and Hadamard gates to avoid auxiliary qubit usage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
int
|
Desired number of uniform terms. |
required |
target_qreg
|
Qubits
|
The register to operate on. |
required |
ctrl
|
Qubits or int
|
Register to control the USP on. Defaults to |
0
|
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the compute. |
{}
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the register passed in is too small. |
AbsoluteDisplacement
Bases: Qubrick
Qubrick for computing the reciprocal of the absolute value of the difference of two vectors.
Specifically, it computes \(\frac{1}{|r1 - r2|} = \frac{1}{\sqrt{(x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2}}\).
Note
Currently, it is on the user to set the constructor args for sub-Qubricks.
A consequence of this is that if you want to allow negative values, this must be
decided when you instantiate the square sub-Qubrick inside of orthogonal_dot_product
rather than in this Qubrick's constructor. Discussions on where this decision should be made
are ongoing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
orthogonal_dot_product
|
Qubrick
|
Qubrick for computing the square of a vector. |
required |
vector_sub
|
Qubrick
|
Adder Qubrick for subtracting Qubit registers. |
required |
rsqrt
|
Qubrick
|
Qubrick for performing the reciprocal square root operation. |
required |
kwargs
|
dict[str, Any]
|
Other key word arguments for the Qubrick. |
{}
|
compute
Compute circuit for taking the absolute value of the difference between two vectors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q_vec1
|
list
|
List of registers encoding vector components for one vector. |
required |
q_vec2
|
list
|
List of registers encoding vector components for the other vector. |
required |
high_precision
|
(Optional, bool)
|
If True, returns high precision output from inverse square-root. Defaults to False. |
False
|
OrthogonalDotProduct
Bases: Qubrick
Qubrick for squaring an n-component vector, then adding the squared results.
Ex. for a 3-component vector computes \(x^2 + y^2 + z^3\).
Note
Currently, it is on the user to set the constructor args for sub-Qubricks.
A consequence of this is that if you want to allow squaring negative values,
this must be decided when you instantiate the square sub-Qubrick rather than
in this Qubrick's constructor. Discussions on where this decision should be made
are ongoing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
release_ancillae
|
bool
|
Whether to release ancillae in the squaring components. |
required |
square
|
Qubrick
|
Qubrick that computes the square of a qubit register. |
required |
add
|
Qubrick
|
Adder Qubrick. |
required |
**kwargs
|
dict[str, Any]
|
Other arguments to pass to the init. |
{}
|
VectorAddition
Bases: Qubrick
Qubrick for adding (or subtracting) the components of two vectors of Qubits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
add
|
Qubrick
|
Adder Qubrick for adding Qubit registers. |
required |
subtract_condition
|
(Optional, bool)
|
Whether to add or subtract the two vectors. Defaults to False (meaning, defaults to adding). |
False
|
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
add
|
Qubrick
|
Adder Qubrick for adding Qubit registers. |
required |
subtract_condition
|
(Optional, bool)
|
Whether to add or subtract the two vectors. Defaults to False (meaning, defaults to adding). |
False
|
kwargs
|
dict[str, Any]
|
Other key word arguments for the Qubrick. |
{}
|
compute
Compute circuit for computing the sum (or difference) of two vectors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q_vec1
|
list
|
List of registers encoding vector components for one vector. |
required |
q_vec2
|
list
|
List of registers encoding vector components for the other vector. |
required |
Note
Two things: (i) The lengths of both vectors must be equal. (ii) Currently, WB cannot handle adding registers of different sizes correctly.
Currently, this method casts the results of addition to QInt objects in order to handle
negative signs. This will be generalized.
BinaryToUnaryComputation
Factory function that creates a BinaryToUnaryUncomputation instance with dagger=True.
This is an alias to make the binary-to-unary conversion more intuitive by avoiding the double negative of "Uncomputation" with dagger=True. This function performs a binary-to-unary conversion by internally using BinaryToUnaryUncomputation with the dagger operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
dict[str, Any]
|
Additional keyword arguments to pass to the BinaryToUnaryUncomputation constructor. The 'dagger' parameter will be set to True regardless of what is passed. |
{}
|
Returns:
| Type | Description |
|---|---|
BinaryToUnaryUncomputation
|
An instance configured for binary-to-unary conversion. |
get_default_multiplex_function
Factory to generate the default multiplexing function.
This default function assumes two kinds of input data
- A PauliSum object.
- A list of integers (to be loaded by, say, a QROM).
This function acts as a factory to return a multiplexing function that applies the element in data at the position given by the index onto the target register controlled on the index qubits being in the binary state representing the index value.
Note
All multiplexing functions must adhere to the contract of having a signature of index (int), index_qubits (Qubits), and ctrl (Qubits or int), such that the multiplexors that call them are promised a certain signature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_reg
|
Qubits
|
The target register to apply the operation on |
required |
data
|
Union[PauliSum, List, Dict]
|
The object storing the operation that should be applied at the given index. Typically a PauliSum, List, or Dict. Examples also include a List/Dict of PauliMasks or a List/Dict of bitmasks |
required |
Returns:
| Type | Description |
|---|---|
Callable
|
multiplexing function |
get_multiplex_function_of_indexed_callables
Factory to generate a multiplexing function when data contains a list of callable operators.
This function acts as a factory to return a multiplexing function that takes the callable given by the first element at the position in "data" given by "index" and calls that operation on the target register controlled on the index qubits being in the binary state representing the index value.
Note
All multiplexing functions must adhere to the contract of having a signature of index (int), index_qubits (Qubits), and ctrl (Qubits or int), such that the multiplexors that call them are promised a certain signature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_reg
|
Qubits
|
The target register to apply the operation on |
required |
data
|
List or Dict
|
The List or Dict storing the callables (as the first element in the Tuple) and any kwargs needed for that callable (as the second element in the Tuple) |
required |
Returns:
| Type | Description |
|---|---|
Callable
|
callable multiplexing function |
get_default_register_permutation_function
Factory to generate the default register permutation function.
This function acts as a factory to return a callable that permutes two qubit registers according to the index passed into the returned callable, which indicates which iteration of the total permutation we are currently on.
All register permutation functions must adhere to the contract of having a signature of permutation_index (int), reg1 (Qubits), reg2 (Qubits), and ctrl (Qubits or int), such that the permutation Qubricks that call them are promised a certain signature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
(Optional, Qubits)
|
An index register which coherently controls the application of quantum operations that effect a permutation of two qubit registers. Defaults to 0, in which case a permutation will occur regardless. |
0
|
Returns:
| Type | Description |
|---|---|
Callable
|
callable register permutation function. |
get_reversed_binary_to_unary_permutation_function
Factory to generate permutation circuits which undo a binary-to-unary conversion.
This function acts as a factory to return a callable that permutes two qubit registers according to the index passed into the returned callable, which indicates which iteration of the total permutation we are currently on.
All register permutation functions must adhere to the contract of having a signature of permutation_index (int), reg1 (Qubits), reg2 (Qubits), and ctrl (Qubits or int), such that the permutation Qubricks that call them are promised a certain signature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index_reg
|
(Optional, Qubits)
|
An index register which coherently controls the application of quantum operations that effect a permutation of two qubit registers. Defaults to 0, in which case a permutation will occur regardless. |
0
|
Returns:
| Type | Description |
|---|---|
Callable
|
callable register permutation function. |