Skip to content

workbench_algorithms.subroutines.quantum_phase_estimation

Main functions to construct circuits for quantum phase estimation.

QPE

QPE(
    bits_of_precision,
    unitary,
    window_kwargs=None,
    window_func=RectWindow(),
    **kwargs,
)

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(
    psi, phase_reg, ctrl: int = 0, **unitary_kwargs
) -> None

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 unitary qubrick.

{}
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.

IterativeQPE

IterativeQPE(
    bits_of_precision,
    unitary,
    window_kwargs=None,
    window_func=RectWindow(),
    **kwargs,
)

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(
    psi, phase_reg, ctrl: int = 0, **unitary_kwargs
) -> None

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 unitary qubrick.

{}
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_precision bit representation of the estimated eigenphase.

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(
    psi, phase_reg, ctrl: int = 0, **unitary_kwargs
) -> None

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 unitary qubrick.

{}
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(
    psi, phase_reg, be_ancilla_reg, ctrl: int = 0, **kwargs
) -> None

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 None. Note that we don't need to control the Hadamards or the inverse QFT as they will cancel on the branch that the controlled unitaries aren't applied on.

0
kwargs dict[str, Any]

Any additional kwargs that need to be passed to the unitary qubrick.

{}

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:

  1. 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.
  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(
    psi, phase_reg, be_ancilla_reg, ctrl: int = 0, **kwargs
) -> None

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 None. Note that we don't need to control the Hadamards or the inverse QFT as they will cancel on the branch that the controlled unitaries aren't applied on.

0
kwargs dict[str, Any]

Any additional kwargs that need to be passed to the unitary qubrick.

{}