Quantum Phase Estimation#

QPE(args, U, precision=None, target=None, iter_spec=False, ctrl_method=None, kwargs={})[source]#

Evaluates the quantum phase estimation algorithm.

The unitary to estimate is expected to be given as Python function, which is called on args.

Parameters:
argslist

A list of arguments (could be QuantumVariables) which represent the state, the quantum phase estimation is performed on.

Ufunction

A Python function, which will receive the list args as arguments in the course of this algorithm.

precisionint, optional

The precision of the estimation. The default is None.

targetQuantumFloat, optional

A target QuantumFloat to perform the estimation into. The default is None. If given neither a precision nor a target, an Exception will be raised.

iter_specbool, optional

If set to True, U will be called with the additional keyword iter = i where i is the amount of iterations to perform (instead of simply calling U for i times). The default is False.

ctrl_methodstring, optional

Allows to specify which method should be used to generate the controlled U circuit. For more information check .control. The default is None.

kwargsdict, optional

A dictionary of keyword arguments to pass to U. The default is {}.

Returns:
resQuantumFloat

The QuantumFloat containing the estimated phase as a fraction of \(2 \pi\).

Raises:
Exception

Tried to perform quantum phase estimation without precision specification.

Examples

We define a function that applies two phase gates onto its input and estimate the applied phase.

from qrisp import p, QuantumVariable, QPE, multi_measurement

def U(qv):
    x = 0.5
    y = 0.125

    p(x*2*np.pi, qv[0])
    p(y*2*np.pi, qv[1])

qv = QuantumVariable(2)

h(qv)

res = QPE(qv, U, precision = 3)
>>> multi_measurement([qv, res])
{('00', 0.0): 0.25,
 ('10', 0.5): 0.25,
 ('01', 0.125): 0.25,
 ('11', 0.625): 0.25}
>>> res.qs.depth()
66

During the phase estimation, U is called \(2^{\text{precision}}\) times. We can reduce that number by abusing that we can bundle repeated calls into a single call with a modified phase.

def U(qv, iter = None):
    x = 0.5
    y = 0.125

    p(x*2*np.pi*iter, qv[0])
    p(y*2*np.pi*iter, qv[1])

qv = QuantumVariable(2)

h(qv)

res = QPE(qv, U, precision = 3, iter_spec = True)
>>> multi_measurement([qv, res])
{('00', 0.0): 0.25,
 ('10', 0.5): 0.25,
 ('01', 0.125): 0.25,
 ('11', 0.625): 0.25}
>>> res.qs.depth()
34