Skip to content

workbench_algorithms.subroutines.multiplexed_usp

Qubrick for implementing multiplexed uniform state preparation.

Contiguizer

Contiguizer(**kwargs)

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(target_reg: Qubits, ctrl: Qubits | int = 0)

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 (no control).

0

MultiplexedRealUSP

MultiplexedRealUSP(
    multiplexor=None, contiguizer=None, **kwargs
)

Bases: Qubrick

Qubrick to perform multiplexed USP.

Note
  • Uses the RealUSP flavor 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

\[\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}}(|00\rangle + |01\rangle) + \frac{1}{\sqrt{3}}(|00\rangle + |01\rangle + |10\rangle)) \]

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 d for the USP calls loaded in superposition.

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, in which case, it is allocated by the Qubrick.

None
succ_reg Qubits

Qubit to herald success. Defaults to None, in which case, it is allocated by the Qubrick.

None
error_param float or int

Parameter determining the accuracy of truncated rotation angles. If None (default), angles are exact and no success qubit is output.

None
ctrl Qubits or int

Optional register to control on. Defaults to 0 (no control).

0
Note

The effect of setting various default args has not been tested.

MultiplexedUSP

MultiplexedUSP(
    multiplexor=None, contiguizer=None, **kwargs
)

Bases: Qubrick

Qubrick to perform multiplexed USP.

Note
  • Uses the USP flavor 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

compute(
    psi,
    index_reg,
    data_reg=None,
    data=None,
    ctrl: int = 0,
    data_bits=None,
) -> 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 \(\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 d for the USP calls loaded in superposition.

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 (no control).

0
data_bits Qubits

Deprecated argument name for data_reg.

None
Note

The effect of setting various default args has not been tested.