Skip to content

workbench_algorithms.subroutines.data_loading.data_lookup_dirty

Qubricks for data lookup oracles.

DataLookupDirtyNaive

DataLookupDirtyNaive(select, swap_up, **kwargs)

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(
    index_reg,
    b,
    data,
    lambda_val=None,
    ctrl: int = 0,
    **kwargs,
) -> None

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 (default), then optimal lambda is calculated.

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

DataLookupDirtyOptimized(select, swap_up, **kwargs)

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(
    index_reg,
    b,
    data,
    lambda_val=None,
    ctrl: int = 0,
    **kwargs,
) -> None

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 (default), then optimal lambda is calculated.

None
ctrl Optional[Qubits, int]

Qreg to control on. Defaults to 0.

0
**kwargs dict[str, Any]

Other arguments to pass to the init.

{}