Skip to content

workbench_algorithms.subroutines.data_loading.data_lookup_clean

Qubricks for data lookup oracles.

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:

  1. 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.

  2. 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.

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

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

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

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.