Skip to content

workbench_algorithms.subroutines.multiplexing.sawtooth

Qubrick for sawtooth multiplexing as per Fig. 5 in arXiv:1805.03662.

SawtoothMultiplexor

SawtoothMultiplexor(max_index=None, **kwargs)

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_max_index(index_val) -> None

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:

  1. There is no data to load (exit the routine).
  2. Loading a single item does not require this hefty machinery.
  3. Loading two items without a control is similarly cheap to the single-item-case.
  4. 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